0

Bash getopts: множественные и обязательные опции

10

Вопрос: Возможно ли использовать getopts для обработки нескольких опций вместе? Например, возможно ли записать команду в формате myscript -iR или myscript -irv?

Кроме того, у меня есть ситуация, при которой в зависимости от условия скрипту потребуется обязательная опция. Например, если аргументом для скрипта является каталог, мне нужно будет указать опцию -R или -r вместе с любыми другими опциями (myscript -iR mydir или myscript -ir mydir или myscript -i -r mydir или myscript -i -R mydir). В случае, если аргументом является файл, опции -i будет достаточно (myscript -i myfile).

Я пытался поискать, но не нашел ответов на этот вопрос.

1 ответ(ов)

1

Вы можете объединить опции, которые вы предоставляете, и getopts сам их разделит. В вашем операторе case вы сможете обработать каждую опцию по отдельности.

Вы можете установить флаг, когда обнаруживаются опции, и проверить, чтобы обязательные «опции» (!) присутствовали после завершения цикла getopts.

Вот пример:

#!/bin/bash
rflag=false
small_r=false
big_r=false
    
usage () { echo "Как использовать"; }
    
options=':ij:rRvhm'
while getopts $options option
do
    case "$option" in
        i  ) i_func;;
        j  ) j_arg=$OPTARG;;
        r  ) rflag=true; small_r=true;;
        R  ) rflag=true; big_r=true;;
        v  ) v_func; other_func;;
        h  ) usage; exit;;
        \? ) echo "Неизвестная опция: -$OPTARG" >&2; exit 1;;
        :  ) echo "Отсутствует аргумент опции для -$OPTARG" >&2; exit 1;;
        *  ) echo "Не реализованная опция: -$option" >&2; exit 1;;
    esac
done

if ((OPTIND == 1))
then
    echo "Не указаны опции"
fi

shift $((OPTIND - 1))

if (($# == 0))
then
    echo "Не указаны позиционные аргументы"
fi
    
if ! $rflag && [[ -d $1 ]]
then
    echo "-r или -R должны быть включены при указании директории" >&2
    exit 1
fi

Это представляет собой полную эталонную реализацию функции getopts, но является лишь наброском для более крупного скрипта.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь