Bash — требуется необязательный аргумент, но он не передается для использования в getopts

Как пометить ошибку в скрипте bash, который требует аргумента для getopt, но пользователь его не передал? например приведенный ниже сценарий требует аргумента для опции «t»:

#!/bin/bash
while getopts "ht:" OPTION
do
    case $OPTION in
        h)
            echo "Hi"
            ;;
        t)
            echo You entered $OPTARG
            ;;
    esac
done

Я хочу поймать ошибку ниже, напечатать что-то еще и выйти. В настоящее время он продолжает оценивать дополнительные аргументы без выхода.

$ ./x.sh -h -t aa     # (this is fine)
Hi
You entered aa

$ ./x.sh -h -t       # (this is not handled)
Hi
No arg for -t option      # (this error is being printed by bash)

person user2511788    schedule 24.05.2015    source источник


Ответы (2)


Здесь несколько моментов:

# Note the leading ':'
while getopts :ht: OPTION
do
    case $OPTION in
        h)
            echo "Hi"
            ;;
        t)
            echo "You entered $OPTARG"
            if [[ ${OPTARG:0:1} == '-' ]]; then
                echo "Invalid value $OPTARG given to -$OPTION" >&2
                exit 1
            fi
            ;;
        :)  echo "$0: -$OPTARG needs a value" >&2; 
            exit 2 
            ;;
        \?) echo "$0: unknown option -$OPTARG" >&2; 
            exit 3
            ;;
    esac
done

Ведущий «:» в списке опций позволяет нам выполнять собственную обработку ошибок. Если указана неизвестная опция, тогда OPTION устанавливается на ?. Обратите внимание, что в операторе case это должно быть экранировано (с префиксом \), иначе оно будет соответствовать любому одиночному символу.

Если значение опции не указано, то OPTION устанавливается на :. К сожалению, это не поможет, если кто-то сделает:

./x -t -h

так как -h будет принято как OPTARG к варианту -t. Отсюда и дополнительное испытание.

Обратите внимание, что все сообщения об ошибках относятся к стандартной ошибке (>&2). Чтобы остановить выполнение скрипта, мы используем exit, за которым следует число в диапазоне 0-255. Единственное число с определенным значением — ноль, что означает успех. Числа от 1 до 255 могут иметь любое значение, которое мы выберем, но все они означают неудачу.

Используя ваши примеры:

./x.sh -t -h
You entered -h
Invalid value -h given to -t

./x.sh -h -t aa
Hi
You entered aa

./x.sh -h -t
Hi
./x.sh: -t needs a value

./x.sh -t tea -c
You entered tea
./x.sh: unknown option -c
person cdarke    schedule 24.05.2015
comment
Отличный ответ, и он отвечает на то, что я хотел спросить дальше. Большое спасибо, ценю вашу помощь. - person user2511788; 24.05.2015

В случае сбоя getopts устанавливает для параметра OPTION знак вопроса (?). Вы должны добавить это к своему делу. Как уже отмечалось, это символ оболочки, требующий экранирования.

getopts — это встроенная функция bash. Помимо проверки явного символа ?, вы также можете использовать переменную bash OPTERR, как указано в Использование getopts в сценарии оболочки bash для получения длинных и коротких параметров командной строки.

Эту информацию лучше всего найти в документации bash. Как ни странно (учитывая количество расширений в bash), он находится в разделе под названием 4.1 Bourne Shell Builtins, и действительно есть POSIX getopts для справки. Однако переменная OPTERR является расширением bash .

person Thomas Dickey    schedule 24.05.2015
comment
Спасибо за эти ссылки и помощь. - person user2511788; 24.05.2015