Bash: while shift; do..case $1 の使い方

Bash: while shift; do..case $1 の使い方

私は 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"

答え1

@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

あなたの間違いは、ループの先頭でシフトし、最初の引数を調べる前にそれを捨てていることです。おそらくあなたが言いたかったのはこれだと思います:

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

echo "$DIR"
echo "$COMMAND"

答え3

chorobaがすでに言ったように、取得より良いアプローチです。

あなたの場合は、以下を使用できます:

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

答え4

通常のアプローチは を使用することですgetopts

関連情報