Несколько параметров для скрипта bash

3

Мне нужно проверить пользовательские опции в моем скрипте bash, но эти опции не всегда будут предоставляться при вызове скрипта. Например, возможными параметрами могут быть -dontbuild -donttest -dontupdate в любой комбинации, есть ли способ проверить их? Извините, если этот вопрос является базовым, я новичок в сценарии bash.

Спасибо

РЕДАКТИРОВАТЬ: я попробовал этот кусок кода, и вызвал сценарий с параметром -disableVenusBld, но он по-прежнему выводит «Начиная сборку». Я делаю что-то неправильно? Заранее спасибо!

while [ $# -ne 0 ]
do
    arg="$1"
    case "$arg" in
        -disableVenusBld)
            disableVenusBld=true
            ;;
        -disableCopperBld)
            disableCopperBld=true
            ;;
        -disableTest)
            disableTest=true
            ;;
        -disableUpdate)
            disableUpdate=true
            ;;
        *)
            nothing="true"
            ;;
    esac
    shift
done

if [ "$disableVenusBld" != true ]; then
    echo "Starting build"
fi
iman453
источник

Ответы:

3

У Денниса была правильная идея, я хотел бы предложить несколько незначительных модов.

Доступ к аргументам сценариев оболочки осуществляется с помощью позиционных параметров $ 1, $ 2, $ 3 и т. Д., А текущий счетчик равен $ #. Классическая проверка для этого будет:

while [ $# -ne 0 ]
do
    ARG="$1"
    shift # get rid of $1, we saved in ARG already
    case "$ARG" in
    -dontbuild)
        DONTBUILD=1
        ;;
    -somethingwithaparam)
        SAVESOMEPARAM="$1"
        shift
        ;;
# ... continue
done

Как говорит Деннис, если ваши требования вписываются в getopts, вам лучше использовать это.

Рич Гомолка
источник
Какую цель делает это таким образом? Это функционально идентично ответу, который я дал, но имеет ненужное условное, переменное назначение и shiftдобавление дополнительного веса.
Деннис Уильямсон
1
Деннис, ты на самом деле не перебираешь аргументы. for argна самом деле не работает в bash, вам нужно ссылаться на $ 1, $ 2 и т. д. Вам нужен сдвиг, чтобы на самом деле перебирать аргументы, и дополнительная переменная ARG должна быть в состоянии использовать сдвиг сразу, поэтому любые параметры в $ 1
Rich Homolka
1
for argделает неявную итерацию, $@так что это, безусловно , работает. Попробуй. Вы также можете сделать это явно с for $arg in $@. Не используя shiftвы можете оставить $@нетронутыми.
Деннис Уильямсон
6
for arg
do
    case "$arg" in
        -dontbuild)
            do_something
            ;;
        -donttest)
            do_something
            ;;
        -dontupdate)
            do_something
            ;;
        *)
            echo "Unknown argument"
            exit 1
            ;;
     esac
done

Где do_somethingпредставляет либо установление флага, либо фактическое выполнение чего-либо. Обратите внимание, что for argнеявно перебирает $@(массив позиционных параметров) и эквивалентно явному for arg in $@.

Также обратите внимание, что Bash имеет встроенную функцию под названием, getoptsно она принимает только короткие опции (например -x). Есть также внешняя утилита, getoptкоторая называется длинная, но имеет несколько недостатков и не рекомендуется.

options=":es:w:d:"

OLDOPTIND=$OPTIND
while getopts $options option
do
  case $option in
    e     ) do_something;;
    w     ) do_something $OPTARG;;
    d     ) foo=$OPTARG;;
    q     ) do_something;;
    s ) case $OPTARG in
                m | M ) bar="abc";;
                s | S ) baz="def";;
                *     ) echo "Invalid option for blah blah" 1>&2; exit;;
        esac;;
    *     ) echo "Unimplemented option chosen.";;   # DEFAULT
  esac
OLDOPTIND=$OPTIND
done
Деннис Уильямсон
источник
Верхняя секция кода не компилируется в #! / Bin / bash: «синтаксическая ошибка рядом с неожиданным токеном« case »»
Майк Бландфорд,
@MikeBlandford: пропал без вести, doкоторый я исправил.
Деннис Уильямсон