set -- "$(getopt abc:d: $*)"
要するに、バグを作成することです。これは ; に固有のものではありませんが、 ;set
の使用には必然的に付随的です。getopt
ただし、 の使用にも一般的です$*
。
次の点を考慮してください。
./yourscript -f"./filename with spaces"
$*
IFS
すべての引数を 1 つの文字列にまとめます。その後、引用符が付けられていないため、これらの引数は:の内容に従って再び./filename with spaces
3 つの引数 : ./filename
、with
、 に分割されspaces
ます。そうしないでください。代わりに、http://mywiki.wooledge.org/BashFAQ/035 のプラクティスに従ってください(そうです、これは BashFAQ と呼ばれますが、POSIX 準拠のメカニズムと bash 固有のメカニズムをカバーしています)。
そうは言っても、何をするつもりなのかを議論するために、以下は実用的な例です:
$ getopt abc:d: -a -c foo bar baz
-a -c foo -- bar baz
getopt
...そして、以下は、使用していない場合でも壊れている理由の例です(単一の引数が 2 つの別々の部分に分割される様子$*
を参照してください):foo bar
foo
bar
$ getopt abc:d: -a -c "foo bar" baz
-a -c foo bar -- baz
...そして、以下は、文字列分割と組み合わせて使用してはならない理由の例ですset --
。これは、引用符で囲まれていない展開 ( など$params
) が複数の引数に分割される方法です。
$ params='-f "foo bar"'
$ set -- $params
$ printf '<%s> ' "$@"; echo
<-a> <"foo> <bar">
代わりに、引数リストに入れるアイテムのリストを管理する正しい方法は、配列を使用することです。POSIX sh では、これを行う正しい方法がまったく許可されていないためです。
$ params=( -f "foo bar" )
$ set -- "${params[@]}"
$ printf '<%s> ' "$@"; echo
<-a> <foo bar>
これらの場合のいずれにおいても、引数ベクトル ( $@
) は、 によって新しい内容で変更されset --
、すべてのオプションの引数の後にのみ位置引数が配置され、 で区切られ--
ます。ただし、間違って変更されています。複数単語の引数は文字列が分割され、間違って再結合されます。繰り返しますが、これを処理する正しい方法については、リンクされた FAQ を参照してください。