web-dev-qa-db-ja.com

必須引数の後または前のオプション引数?

シェルスクリプトを作成していますが、2つの必須の引数と1つのオプションの引数を取る必要があります。どうすれば確認できますか?私が見たほとんどのスクリプトでは、次のようにオプションの引数が必須の引数の前に渡されます。

cut -c2 test.txt

しかし、私にとって、このパターンはスクリプトでチェックするのが複雑になるので、私の考えは、3番目の引数をオプションと見なすことです。

6
Cold

オプションの引数が最後にある場合は、これを行うことができます:

foo=$1
bar=$2
baz=${3:-default value}

最初の2つの引数は$foo$barに格納されます。 3番目の引数が指定された場合、それは$bazに格納されます。それ以外の場合は、デフォルトでdefault valueになります。 3番目の変数が空かどうかを確認することもできます。

if [ -z "$3" ]; then
    # Code for the case that the user didn't pass a third argument
fi

最初にデフォルトを使用したい場合、おそらく最も簡単な方法は、$#に格納されているスクリプトに渡された引数の数を確認することです。例えば:

case $# in
  2)
    # Put commands here for when the user passes two arguments
    # Could just be setting variables like above, or anything else you need
    ;;
  3)
    # Put commands here for when the user passes three arguments
    ;;
  *)
    echo "Wrong number of arguments passed"
    exit 1;;
esac

エラーチェックが必要な場合、$#をオンにしてもどちらの場合でも問題なく機能します。スクリプトがcutの例のようなgetoptスタイルの引数を使用する場合、それを使用できます。詳細については このスタックオーバーフローの質問 を参照してください

6
Michael Mrozek

オプションの引数を最初に置く1つの方法は、shiftを使用することです。
すべての引数をnステップ左に移動し、下にあるものを削除します$1shiftに引数が指定されていない場合、ステップ数は1です。

スクリプトの最初に、最初の引数がオプションの引数の構造または最初に必要な引数と一致するかどうかを確認します。
必要な場合は、何もしません。
それがオプションの場合は、処理してshiftを呼び出します。

ここで便利なのは、オプションの引数が指定されているかどうかに関係なく、必要な引数、たとえば3があるとすると、常に$1から$3afterオプションの引数が処理されるブロック。

0
miyalys

必須とオプションの引数、およびオプションとオペランドの2つの異なる概念があります。オプションは-で始まる引数であり、オペランドは-で始まらない引数であり、オプションの引数ではありません。オプションは名前で識別され、通常は任意の順序にすることができます。オペランドはその位置によって識別されます。だから

someprogram -a -z -c foo bar

3つのオプション-a-cおよび-zがあり、2つのオペランドがあります。1つはfooで、2つ目はbarです。

オプションは通常、オペランドの前に置かれます。 GNUプログラムは順序を気にしない傾向がありますが、GNU以外のほとんどのプログラムは-で始まる引数を、その前に別のオペランドがある場合はオペランドとして扱います。オプションには多くのバリエーションがあります(グループ化、--など)ここでは説明しません。

プログラムが2つの必須オペランドと3番目のオプションオペランドを取る場合、自然な方法は必須オペランドを最初のオペランドと2番目のオペランドにし、3番目のオペランドが存在する場合はオプションのオペランドにすることです。

シェルスクリプトでは、引数は"$1""$2""$3"などです。引数の数は$#です。スクリプトがオプションを認識しない場合は、オプションの検出を省略して、すべての引数をオペランドとして扱うことができます。サンプルコードについては Michael Mrozekの回答 を参照してください。オプションを認識したい場合は、getoptsビルトインを使用してください(例については、シェルのドキュメントを参照してください)。