4

Я работаю над сценарием Bash, и мне нужно реализовать "параметры". Как я могу сделать это с Bash?

Моя цель - запустить скрипт следующим образом:/myscript.sh -d "/var/log/" -c "test"

что я пробовал:

while shift; do
        case $1 in
                -d)
                        shift&&DIR="$1"||die
                ;;
                -c)
                        shift&&COMMAND="$1"||die
                ;;
        esac
done

echo "$DIR"
echo "$COMMAND"

4 ответа4

6

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

#!/bin/bash
while (( "$#" )); do
   case $1 in
      -d)
         shift&&DIR="$1"||die
         ;;
      -c)
         shift&&COMMAND="$1"||die
         ;;
   esac
   shift
done

echo "$DIR"
echo "$COMMAND"
5

Чтобы расширить ответ @ choroba, вот пример того, как использовать getopts:

# parse the flag options (and their arguments)
while getopts c:d: OPT; do
    case "$OPT" in
      d)
        DIR="$OPTARG" ;;
      c)
        COMMAND="$OPTARG" ;;
      [?])
        # got invalid option
        echo "Usage: $0 [-d directory] [-c command]" >&2
        exit 1 ;;
    esac
done

# get rid of the just-finished flag arguments
shift $(($OPTIND-1))

Обратите внимание, что после смещения аргументов флага все "обычные" аргументы останутся. Таким образом, в этот момент вы можете иметь дело с ними (например ... for arg in "$@"; do ...), или если ваш скрипт не принимает их, просто цепляйтесь, если вы их получили (if [ $# -gt 0 ]; then echo "Usage ...).

2

Как уже сказал Чороба , getopts - лучший подход.

В вашем случае вы можете использовать:

getopts c:d: d || die
DIR=$OPTARG
getopts c:d: c || die
COMMAND=$OPTARG

добиться того, что вы пытаетесь сделать с помощью цикла while.

Строка c:d: указывает возможные ключи. Двоеточие означает, что для переключения требуется аргумент.

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

Чтобы это исправить, измените цикл while на следующее:

while true; do
        case $1 in
                -d)
                        shift&&DIR="$1"||die
                ;;
                -c)
                        shift&&COMMAND="$1"||die
                ;;
        esac
        shift || break
done
1

Обычный подход заключается в использовании getopts .

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .