nullglobがデフォルトではないのはなぜですか?

nullglobがデフォルトではないのはなぜですか?

これはほとんどのシェルではnullglobデフォルト設定ではありません。これは、たとえば、このコマンドを実行した場合

ls *

空のディレクトリでは、空の引数リストの代わりに*globをテキストに展開します。空のパラメータリストが空のディレクトリに返される*ように、この動作を変更する方法があります。これはより直感的に見えます。*

nullglobそれでは、デフォルトで無効になっている理由はありますか?では、なぜそうなのでしょうか?

ベストアンサー1

nullglobほとんどの場合、このオプションは理想的ではありません。ls良い例は次のとおりです。

ls *.txt

または、より正確な表現は次のとおりです。

ls -- *.txt

.txt(タイプを除く名前が次に終わるファイルのリスト)目次-dその内容がリストされています。おそらく、特別な扱いを避けるためにこのオプションを使用しようとします。目次文書)。

一致するファイルがない場合、onはnullglob引数なしで実行され、これは(現在のディレクトリの内容の一覧表示)lsとして扱われ、これはリテラルを引数として呼び出すよりも悪い可能性があります。ls -- .ls*.txt

ほとんどのテキストユーティリティにも同様の問題があります。

grep foo *.txt

fooファイルが存在しない場合は、標準入力で検索が実行されますtxt

csh、tcsh、zsh、またはFish 2.3 +(および以前のUnixシェル)のデフォルト値であるより合理的なデフォルト値は、globが一致しない場合はコマンドを完全にキャンセルすることです。

bash(バージョン3以降)オプションがありますfailglob(この議論は、ashAT&Tとは異なり、kshまたはオプションのローカルスコープをサポートしていzshないbash3とは異なり、グローバルに有効にすると、bash-completion機能などの一部の機能が中断されるため興味深いものです)。

zshcshとtcshは、次の場合とはfish若干異なります。bash -O failglob

ls -- *.txt *.html

コマンドを取り消すには、すべてのグローバル変数が一致しないようにしてください。たとえば、txtファイルはありますが、htmlファイルがない場合は次のようになります。

ls -- file.txt

with を使用してこの動作を取得できますが、zshよりset -o cshnullglob合理的なアプローチzshは、次のようなglobを使用することです。

ls -- *.(txt|html)

zshでもksh93申請できます。空のボールグローバルごとに見ると、これはグローバル設定を変更するよりも合理的なアプローチです。

files=( *.txt(N)  ) # zsh
files=( ~(N)*.txt ) # ksh93

ファイルが存在しない場合、txtエラーのためにコマンドが失敗するのではなく空の配列が生成されます(または*.txt別のシェルを使用して1つのリテラル引数を持つ配列にします)。

fish2.3以前のバージョンも同様に機能していましたが、bash -O nullglob対話中にglobが一致しない場合は警告が表示されました。 2.3 以降は、zshまたは で使用された glob とは異なって動作します。forsetcount

歴史的に、これらの行動は実際に壊れたBourne シェルとして実装されます。以前のバージョンのUnixでは、ワイルドカードの割り当ては次のよう/etc/globに機能するヘルパーを介して行われましたcsh。ファイルに一致するワイルドカードがないとコマンドは失敗し、そうでないと一致するワイルドカードは削除されません。

したがって、今日私たちが持っている状況は、Bourneシェルから下された誤った決定によるものです。

Bourneシェル(およびCシェル)には、別の新しいUnix機能である環境が付属しています。これは変数拡張を意味します (以前のバージョンには$1$2... 位置引数だけありました)。 Bourne シェルにはコマンド置換も導入されました。

Bourneシェルのもう1つの誤った設計決定は、変数の拡張とコマンドの置き換えにワイルドカード(および分割)を実行することです(おそらくワイルドカードが含まれている場合はまだ呼び出されるThompsonシェルとの下位互換性のため)echo $1(プリプロセッサマクロと似ています)拡張)拡張値は再びシェルコードに解析されるため))。/etc/glob$1

たとえば、一致しない失敗したglobは、次のことを意味します。

pattern='a.*b'
grep $pattern file

コマンドが失敗します(a.whateverb現在のディレクトリにいくつかのファイルがない場合)。 (変数拡張時にもワイルドカードを実行します。)この場合、コマンドは失敗します。 ( //cshのようにワイルドカードをまったく使用しないほど良くなくても休眠エラーをそのままにするよりは良いと思います。 .. )。rczshfish


shopt組み込み機能は1996年2.0に追加され、zshそのオプションbashにちなんで命名されました。allow_null_glob_expansion 変える以前のバージョンの場合

²その間隔内にファイルが作成されていないか、現在のディレクトリが検索可能であるが読み取れず、ファイルまたはディレクトリが存在しない限り、ファイルなしエラーが報告されることがlsあります。たとえば、試した後*.txtmkdir -p '*.txt/wtf'; chmod a=,u=wx .

set -o3バージョン4.4では、Almquistシェルと同様にオプションセットをローカル関数に設定できますが、2番目のオプションセット(オプションセットを含む)では機能しlocal -ないため、これにはいくつかの改善がありました。bashshopt

おすすめ記事