POSIXシェルスクリプトのこれらのネストされたオプションがトークン化されるのはなぜですか?

POSIXシェルスクリプトのこれらのネストされたオプションがトークン化されるのはなぜですか?

count_argsパラメータを計算するスクリプトがあります。

#!/bin/sh
echo $#

これらのオプションを使用して呼び出すと、2つのパラメータがあることを知らせます。

$ ./count_args --options '1 2'
2

ただし、スクリプトでパラメータをtest_args次のように設定した場合:

#!/bin/sh
ARGS="--options '1 2'"
./count_args ${ARGS}

...結果は次のとおりです。

$ ./test_args 
3

'1 2'スクリプトに分割があるのはなぜですか? POSIX準拠の方法でこれを防ぐにはどうすればよいですか?次からスクリプトを呼び出す?より複雑なスクリプト(haveARGS_1やなどARGS_2)からパラメータを分離できるように、パラメータを変数に保存することはまだ可能ですか?

私のもの/bin/shですdash

答え1

最初のケースでは、渡された引数はcount_argsシェルによって解釈され、シェルは2つの単語を見てそれに渡します--options1 2count_args

2番目のケースでは、二重引用符で囲まれた文字$以外のすべての文字が\リテラルとして扱われます。シェルが一重引用符を解釈するには遅すぎます。シェルは$ARGS変数の内容を長い文字列として扱い、--options '1 2'すべての文字はリテラルとして扱われ、シェルに特別な意味はありません。

${ARGS}二重引用符なしで使用すると、フィールドが分​​割され、ファイル名が拡張されます。デフォルト値を使用すると、とのIFS3つの別々の単語が表示されます。--options'12'

アーカイブする最良の方法は、次のものを使用することです"$@"

#!/bin/sh

set -- --options '1 2'

./count_args "$@"

関連情報