nullglob
(BTWあるオプションzsh
のみに年後に加え、本発明、bash
(2.0
))は、多くの場合理想的ではないであろう。そしてls
良い例です:
ls *.txt
または、より適切な同等物:
ls -- *.txt
nullglob
実行します上ls
として扱われる引数なしでls -- .
呼び出すよりもおそらく悪いです何のファイルが一致しない場合(カレントディレクトリをリスト)、ls
リテラルを*.txt
引数として。
ほとんどのテキストユーティリティで同様の問題が発生します。
grep foo *.txt
ファイルfoo
がない場合は、stdinを探しtxt
ます。
より賢明なデフォルト、およびcsh、tcsh、zshまたはfish 2.3+(および初期のUnixシェル)の1つは、globが一致しない場合にコマンドを完全にキャンセルすることです。
bash
(バージョン3以降)にはfailglob
オプションがあります(この議論に興味があるのはash
、AT&T ksh
またはzsh
に反して、 bash
オプションのローカルスコープをサポートしていないためです(4.4で変更されます)が、グローバルに有効にすると、いくつかのことが壊れますbash-completion関数など)。
cshとtcshはzsh
、fish
または次のbash -O failglob
ような場合とわずかに異なることに注意してください。
ls -- *.txt *.html
コマンドをキャンセルするためにすべてのグロブが一致しない必要がある場合。たとえば、1つのtxtファイルがあり、htmlファイルがない場合、次のようになります。
ls -- file.txt
あなたがその動作を得ることができるzsh
とsetopt cshnullglob
それを行うには、より賢明な方法はかかわらzsh
ようグロブを使用することです:
ls -- *.(txt|html)
でzsh
とksh93
、あなたも適用することができnullglobをグローバル設定を変更するよりも多くの正気のアプローチがあるごとグロブごと、上:
files=(*.txt(N)) # zsh
files=(~(N)*.txt) # ksh93
txt
ファイルがない場合、エラーでコマンドが失敗する(または*.txt
、他のシェルで1つのリテラル引数を持つ配列になる)代わりに、空の配列が作成されます。
fish
2.3より前のバージョンは同様に機能しますbash -O nullglob
が、グロブに一致するものがない場合に対話型の場合は警告が表示されます。2.3以降、またはでzsh
使用されるグロブを除き、同様に機能します。for
set
count
さて、ヒストリーノートでは、この動作は実際にはBourneシェルによって壊れていました。Unixの以前のバージョンでは、グロビングは/etc/glob
ヘルパーを介して行われ、そのヘルパーは次のように動作しました。グロブがcsh
いずれのファイルにも一致しない場合はコマンドが失敗し、そうでない場合はグロブが削除されます。
したがって、今日の状況は、Bourneシェルで行われた不適切な決定によるものです。
Bourneシェル(およびCシェル)には、別の新しいUNIX機能である環境が付属していることに注意してください。つまり、変数の展開を意味します(前身は$1
、$2
...位置パラメーターのみを持っていました)。Bourneシェルでは、コマンド置換も導入されました。
Bourneシェルの別の貧弱な設計決定は、変数の展開およびコマンド置換でグロブ(および分割)を実行することでした(おそらく、ワイルドカードが含まれている場合にecho $1
起動するThompsonシェルとの下位互換性のためです)展開された値がシェルコードとして再度解析されたように))。/etc/glob
$1
一致しないグロブの失敗は、たとえば次のことを意味します。
pattern='a.*b'
grep $pattern file
(a.whateverb
現在のディレクトリにいくつかのファイルがない限り)コマンドは失敗します。csh
(変数の展開時にグロビングも実行します)その場合、コマンドは失敗します(そして、のようにグロビングをまったく行わないほど良くない場合でも、休止中のバグをそこに残すよりも良いと主張しますzsh
)。