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準拠の方法でこれを回避するにはどうすればよいですか?呼び出しスクリプトからARGS_1? より複雑なスクリプト (たとえば、と を持つARGS_2)で引数を分離できるように、何らかの方法で引数を変数に格納することは可能ですか?

なお、 my は/bin/shですdash

答え1

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

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

二重引用符なしで使用すると${ARGS}、フィールド分割とファイル名の拡張の対象になります。 のデフォルト値を使用すると、 、 という3IFSつの区切られた単語が生成されます。--options'12'

これをアーカイブする最良の方法は以下を使用することです"$@":

#!/bin/sh

set -- --options '1 2'

./count_args "$@"

関連情報