別の質問では、私が使用するように提案されました。
shopt -s extglob
問題を解決する。私の考えでは、このタイプのコマンドは慎重に使用する必要があるということです。それはおそらく他のスクリプトに望ましくない影響を与える可能性があるからです。誰でもこれについて話すことができますか?
答え1
shopt
コマンドを実行するシェルの動作にのみ影響します。これを入力すると、非~/.bashrc
ログインインタラクティブシェルとrsh / sshを介して実行されるコマンドに影響します(または~/.bashrc
で起動した場合は、~/.profile
ログインシェルも影響を受ける可能性があります~/.bash_profile
)。
環境変数をに設定すると、BASHOPTS
そのextglob
環境変数が設定されたときに実行されるすべての対話型または非対話型bashシェルに影響します(呼び出されない限りsh
)。
インタラクティブシェルはextglob
使用したい場所なので、設定したい場所なので、~/.bashrc
すべてのインタラクティブシェルの利点を活用するのに最適な場所です。スクリプトで使用するには、スクリプトの先頭に追加するだけです。
問題を引き起こす可能性のある唯一の場所は設定されているため、作成していない一部のコードは設定されるとは予想されません。たとえば、これはあなたのスクリプトです。源泉メッセージが表示されるか、~/.bashrc
オプションを設定した後。
一部のオプションでは、これは本当ですが、そうではありません。extglob
Bourneシェルとの下位互換性を維持するために(そして構文がなぜそんなに厄介なのかを説明するために)慎重に設計されたからです(kshのDavid Kornによって)。
デフォルトでは、拡張globを使用するすべてはBourneシェルまたはPOSIXシェル構文で構文エラーを引き起こします。 Bourne または POSIX スクリプトにある場合、echo @(a)
壊れることがあります (引用符のない括弧のため)。突然エラーメッセージの代わりに「a」が出力され始めても大丈夫です。
bashにはzshなどの代替拡張glob構文がないため、bashがデフォルトでなぜそれを有効にしないのかわかりません。
編集する。 David KornはBourne / POSIXの互換性を破らないように懸命に努力していますが、bashはそれほど気にしないようです。これがおそらくkshのようにデフォルトで有効になっていない理由です。
ksh(およびkshエミュレーションのzsh)では、引数またはコマンドの置換時にワイルドカードを実行すると拡張ワイルドカードが無効になります。
$ touch a
$ a='@(a)' ksh93 -c 'echo $a'
@(a)
Bashではそうではありません。
$ a='@(a)' BASHOPTS=extglob bash -c 'echo $a'
a