未使用のgetopts引数の処理(オプションは必須ではありませんか?)

未使用のgetopts引数の処理(オプションは必須ではありませんか?)

getoptsで始まり、次のスクリプトがあります。

USAGE() { echo -e "Usage: bash $0 [-w <in-dir>] [-o <out-dir>] [-c <template1>] [-t <template2>] \n" 1>&2; exit 1; }

if (($# == 0))
then
    USAGE
fi

while getopts ":w:o:c:t:h" opt
do
    case $opt in
        w ) BIGWIGS=$OPTARG
        ;;
        o ) OUTDIR=$OPTARG
        ;;
        c ) CONTAINER=$OPTARG
        ;;
        t ) TRACK=$OPTARG
        ;;
        h ) USAGE
        ;;
        \? ) echo "Invalid option: -$OPTARG exiting" >&2
       exit
        ;;
        : ) echo "Option -$OPTARG requires an argument" >&2
        exit
        ;;
    esac
done

more commands etc

echo $OUTDIR
echo $CONTAINER

私はこのスクリプトについていくつかのテストをしていますが、いくつかの手順では-cパラメータ[-c]を使用する必要はありませんし、使用したくありません。つまり、$ CONTAINER変数をまったく含まないスクリプトの別の特定の部分をテストしようとします。だから私は$ CONTAINERのすべてのコマンドの前に#を追加していくつかのテストを試してみました。

$CONTAINER を使用せずにスクリプトをテストする場合は、次のように入力します。

bash script.bash -w mydir -o myoutdir -t mywantedtemplate

しかし、getoptsコマンドが与えられたときに警告が表示されないかどうか疑問に思います。つまり、-cパラメータが必要であるという警告が表示されないのはなぜですか?可能ですか?次のように入力すると警告が表示されます。

bash script.bash -w mydir -o myoutdir -t mywantedtemplate -c

修正する

いくつかのテストを経た後、私は次のように考えました。

  • 明示的に「-c」を書かないと、getoptsは「質問」せずにエラーを表示します(スクリプトがそれを使用して何かをしない限り - つまり、各コマンドの前に#を入れていない場合)。この主張)
  • 「-c」のみを入力し、何も入力しないとエラーが発生します。

そうですか?おそらく私がしたことは「悪い習慣」だったので避けなければなりません。テストするときは、getoptsコマンドからc:を完全に削除する必要がありました。

私が尋ねるものは次のとおりです。 getoptsにパラメータ(私のスクリプトの「while」行)について知らせるとき、私たちは次のように言います。これは予想されるオプションであり、「:」の後に続くオプションにはパラメータが必要です。それらを 。しかし、それらは与えられる必要はありません。つまり、引数を含むcオプションを期待できますが、cオプションがまったく指定されていなくてもエラーは発生しません。

答え1

ユーティリティgetoptsはわからない必須オプション、どのオプションが許可されるか(そしてどのオプションがオプション引数を取るべきか)についてのみ説明します。必須オプションを適用するには、オプション解析ループの内側または後で独自のテストを実行する必要があります。

getopts一部のオプションが競合したり、一部のオプションに異なるオプションが必要であるなど、オプションがより複雑な関係を持つ可能性があるため、ユーティリティはこれを実行しません。これは、スクリプト作成者が自分のロジックに従ってクリーンアップすることを残します。

答え2

あなたが何を求めているのかはわかりませんが、それがすることは、getoptsプログラムに提供されているコマンドラインを解析し、ウィンドウに表示されるオプションを1つずつポップアップすることです。プログラムコードは扱いやすい形式になっています。不明なオプションのエラーを印刷するオプションがありますが、それはすべてです。

getopts呼び出し時にコマンドラインがすでに変更されているため、実際には誰にも「要求」しません。プログラムの残りの部分がそれを実装しない限り、相互作用はありません。

また、プログラムを実行するために必要なオプションがわかりません(パラメータgetopts「optstring」にはその構文はありません)。通常の状況はいいえオプションは必須です(たとえばls、、、rm... vi)。必要なオプションがある場合は、スクリプトで手動で確認できます。

次の例を考えてみましょう。

#!/bin/bash

opt_a=
opt_b=
while getopts 'a:bc' opt; do
    case $opt in
        a) opt_a=$OPTARG;;
        b) opt_b=1;;
    esac
done

if [ -z "$opt_a" ]; then
    echo "option a was NOT given, exit."
    exit 1;
fi
echo "do something with a='$opt_a' b=$opt_b"

スクリプトはaそれが提供されていることを明示的に確認します。確認しないと、プログラムは引き続き実行されます。また、オプションとしてgetopts受け入れるように求められ、エラーは発生しません。ケースやケースcを入れなかったため、スクリプトはこれを完全に無視しました。この特定のオプションが無視されるかどうかを知る方法はありません。c)*)getopts

プロンプトで角かっこを使用する一般的な意味は、オプションがオプションであることを示すことであるため、すべての、、、、をスクリプト-wに提供する必要があることを意味する場合は、角かっこを削除することをお勧めします。-o-c-t

関連情報