0

これは、OPTS で取得および設定する正しい方法ですか?

みたいな選択肢をたくさん取り入れたい

./runthis.sh --option1 setuff --option2 setmorestuff

while :
do
        case $1 in
                -h | --help | -\?)
                        usage
                        exit 0
                        ;;
                -o | --option1)
                        O=$2
                        shift 2
                        ;;
                -z | --option2)
                        Z=$2
                        shift 2
                        ;;
                --) # End of all options
                        shift
                        break
                        ;;
                -*)
                        echo "WARN: Unknown option (ignored): $1" >&2
                        shift
                        ;;
                *)  # no more options. Stop while loop
                        break
                        ;;
        esac
done
4

1 に答える 1

1

オプションを解析したい場合は、すぐに利用できる 2 つのオプションがあります。

  1. getopts (これについては getopts チュートリアルを参照できます)
  2. 手動解析 (ここで説明します)

getopts を使用する方が簡単ですが、柔軟ではありません。あなたのコードはほとんど正しいですが、より一般的なオプションの解析には適していません。

  1. chepner が述べたように、while trueは と同じwhile :です。前者は、何をしているかがすぐに直感的にわかるため、好まれます。これは私たちが話しているbashであり、perlではありません。不必要な難読化は必要ありません。
  2. while trueオプションを解析するための適切なループ終了条件ではありません。考えてみると、ループが何をしているのかは何もわかりません。何が起こっているのかを理解するために、あなたの最後のケースまで行かなければなりません。適切なループ終了条件は、コマンド ライン引数を使い果たしたときです。
  3. ループが何らかの形式の均一なループを実行していることは、すぐにはわかりません。位置パラメータ配列をシフトしていることを確認するには、各ケースを読む必要があります。shift反復ごとに少なくとも 1 つ実行するので、実行してください。
  4. #2に結び付けて、*)ループ終了をチェックするために使用することはお勧めできません。空の文字列は次のように一致します。

    ./foo.sh --option1 "" --option2 123

    ご覧のとおりoption2、コードを使用してその値を取得することはありません。幸いなことに、#2 でこの問題も修正されます。

  5. 最後に 1 点: 変数にスペースが含まれていないことが確実でない限り、すべての変数をクォートする必要があります。bash での空白の分割は変数置換の後に発生するため、スペースは本当にあなたを台無しにする可能性があります。よくわからない場合は、引用してください。

コードの改訂版は次のようになります。

while [ $# -gt 0 ]
do
        case "$1" in
                -h | --help | -\?)
                        usage
                        exit 0
                        ;;
                -o | --option1)
                        O="$2"
                        shift
                        ;;
                -z | --option2)
                        Z="$2"
                        shift
                        ;;
                --) # End of all options
                        shift
                        break
                        ;;
                *)
                        echo "WARN: Unknown option (ignored): $1" >&2
                        break
                        ;;
        esac
        shift
done
于 2012-10-30T03:24:03.297 に答える