Треппинг недопустимых опций getopt - PullRequest
12 голосов
/ 05 октября 2011

Я использую getopt (не getops), чтобы предоставить моему сценарию bash возможность обрабатывать параметры и переключатели (как длинные --option, так и короткие -o формы).

I 'Я хотел бы иметь возможность отлавливать недопустимые параметры и обрабатывать их, как правило, повторяя, что пользователь должен попробовать cmd --help, а затем выйти из сценария.

Дело в том, что недопустимые параметры перехватываются getopt, которыйСам вывод сообщения, такого как "getopt: invalid option - 'x'"

Вот шаблон, который я использую для установки моих параметров getopt:

set -- $(getopt -o $SHORT_OPTIONS -l $LONG_OPTIONS -- "$@")

, где $ LONG_OPTIONS и$ SHORT_OPTIONS - это список параметров, разделенных запятыми.

Вот как я обрабатываю обработку параметров:

 while [ $# -gt 0 ]
    do
        case "$1" in
            -h|--help)
                cat <<END_HELP_OUTPUT

    Help
    ----

    Usage: ./cmd.sh 

    END_HELP_OUTPUT

                shift;
                exit
                ;;
            --opt1)
                FLAG1=true
                shift
                ;;
            --opt2)
                FLAG2=true
                shift
                ;;
            --)
                shift
                break
                ;;
            *)
                echo "Option $1 is not a valid option."
                echo "Try './cmd.sh --help for more information."
                shift
                exit
                ;;
        esac
    done

getopt -q будет подавлять вывод, но моя схема перехвата в case заявление по-прежнему не в состоянии сделать то, что я ожидаю.Вместо этого программа просто выполняется, несмотря на неверные аргументы.

Ответы [ 6 ]

9 голосов
/ 06 октября 2011

Этот стиль работает для меня:

params="$(getopt -o d:h -l diff:,help --name "$cmdname" -- "$@")"

if [ $? -ne 0 ]
then
    usage
fi

eval set -- "$params"
unset params

while true
do
    case $1 in
        -d|--diff)
            diff_exec=(${2-})
            shift 2
            ;;
        -h|--help)
            usage
            exit
            ;;
        --)
            shift
            break
            ;;
        *)
            usage
            ;;
    esac
done
1 голос
/ 19 июля 2013

Я обнаружил, что это работает как последний элемент в выражении дела getopts:

*) eval echo "Unrecognized arg \ $$ [OPTIND-1]";использование;выход ;;

1 голос
/ 30 марта 2013

Вам вообще нужно использовать getopt?Если вы просто используете

while [ $# -gt 0 ]; do
  case "$1" in
    -d|--diff)
       diff_exec=(${2-})
       shift
       ;;
    -h|--help)
       usage
       exit
       ;;
     --)
       break
       ;;
     *)
       usage
       ;;
    esac
    shift
done

, тогда ваш собственный код выполняет проверку.

1 голос
/ 06 июня 2012

Это не самое надежное решение, но оно разумно; он опирается на следующее:

  • Сообщение об ошибке, что getopt печатает с префиксом "getopt:"
  • Предполагается, что допустимо пройти очищенную версию сообщения об ошибке getopt, дополненного пользовательской информацией.

Фрагмент кода:

# Invoke getopt; suppress its stderr initially.
args=$(getopt -o $SHORT_OPTIONS -l $LONG_OPTIONS -- "$@" 2>/dev/null)
if [[ $? -ne 0 ]]; then # getopt reported failure
    # Rerun the same getopt command so we can capture stderr output *only* this time.
    # Inefficient (and a potential maintenance headache, if literals were involved), but this will only execute in case of invalid input.
    # Alternatively, redirect the first getopt invocation's stderr output to a temp. file and read it here.
    errmsg=$(getopt -o $SHORT_OPTIONS -l $LONG_OPTIONS -- "$@" 2>&1 1>&-)
    # Strip getopt's prefix and augment with custom information.
    echo -e "${errmsg#getopt: }\nTry './cmd.sh --help for more information." 1>&2
    exit 1
fi
0 голосов
/ 02 ноября 2013

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

Для командной строки: -a AA -b BB -c CC, результат s / b a = AA b = BB c = CC

OPT=( "$@" )  # Parses the command line into words.

for [[ I=0;I<${#OPT[@]};I++ ]]  
   do
      case "${OPT[$I]}" in         
         -a) a=${OPT[$I+1]} ;;         
         -b) b=${OPT[$I+1]} ;;         
         -c) c=${OPT[$I+1]} ;;    
      esac
  done
0 голосов
/ 05 октября 2011

Я не уверен, может ли это помочь, но getopt (1) использует getopt (3) и, если я правильно помню, getopt (3) подавить сообщение об ошибке, если первый символ OPTSTRING является двоеточием.

...