set -- "$(getopt abc:d: $*)"要するに、バグを作成することです。これは ; に固有のものではありませんが、 ;setの使用には必然的に付随的です。getoptただし、 の使用にも一般的です$*。
次の点を考慮してください。
./yourscript -f"./filename with spaces"
$*IFSすべての引数を 1 つの文字列にまとめます。その後、引用符が付けられていないため、これらの引数は:の内容に従って再び./filename with spaces3 つの引数 : ./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 barfoobar
$ 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 を参照してください。