nullglob
Seçeneği (BTW bir olan zsh
buluş, yalnızca yıl sonra eklenen bash
( 2.0
vakaların bir dizi ideal olmaz)). Ve ls
iyi bir örnek:
ls *.txt
Veya daha doğru bir eşdeğeri:
ls -- *.txt
nullglob
On ile , hiçbir dosya eşleşmiyorsa (geçerli dizini listele) ls
herhangi bir argüman olmadan çalışır ls -- .
, muhtemelen argüman olarak ls
değişmez *.txt
olarak çağırmaktan daha kötüdür .
Çoğu metin yardımcı programında benzer sorunlarınız olur:
grep foo *.txt
İçin bakar mısın foo
hiç olmadığını stdin txt
dosyası.
Daha mantıklı bir varsayılan ve csh, tcsh, zsh veya fish 2.3+ (ve erken Unix kabuklarından) biri, eğer dünya uyuşmazsa, komutu tamamen iptal etmektir.
bash
(sürüm 3 beri) bir sahiptir failglob
aksine beri bu tartışmaya ilginç bunun için bir seçenek ( ash
AT & T ksh
veya zsh
, bash
o) 4.4 değiştirmek olsa (seçenekler için yerel kapsamları desteklemez, bir kaç şey kırıldığında küresel etkinleştirilenler seçeneği bash tamamlama işlevleri gibi).
O csh ve tcsh gelen biraz farklı olduğunu unutmayın zsh
, fish
ya bash -O failglob
benzeri durumlarda:
ls -- *.txt *.html
Komutun iptal edilmesi için bütün dünyaların eşleşmemesi gereken yerde. Örneğin, bir txt dosyası varsa ve html dosyası yoksa, bu olur:
ls -- file.txt
Bunu yapmanın daha mantıklı bir yolu zsh
ile bu davranışı elde edebilirsiniz :setopt cshnullglob
zsh
ls -- *.(txt|html)
Gelen zsh
ve ksh93
, ayrıca uygulayabilirsiniz nullglob bir genel ayarı değiştirerek çok daha saner yaklaşımdır başına glob temelinde:
files=(*.txt(N)) # zsh
files=(~(N)*.txt) # ksh93
txt
Komutu bir hatayla atmak yerine dosya yoksa (ya *.txt
da diğer kabukları ile tek bir hazır bilgi argümanı olan bir dizi yapmak) boş bir dizi oluşturur .
fish
2.3'ten önceki sürümler, bash -O nullglob
bir globun eşleşmediği durumlarda etkileşimli olduğunda bir uyarı verir ancak bir uyarı verir. 2.3 yana, gibi çalışır zsh
kullanılan Neználkovo haricinde for
, set
ya da count
.
Şimdi, tarih notunda, davranış aslında Bourne kabuğu tarafından kırılmıştı . Unix'in önceki sürümlerinde, globbing /etc/glob
yardımcısı aracılığıyla yapıldı ve bu yardımcı şu şekilde davrandı csh
: herhangi bir dosya eşleşmediyse, komutları başarısızlığa uğratmaz ve globları aksi takdirde eşleşmeden kaldırırdı.
Bu yüzden bugün içinde bulunduğumuz durum Bourne kabuğundaki kötü bir karardan kaynaklanıyor.
Bourne kabuğunun (ve C kabuğunun) başka bir yeni Unix özelliği ile geldiğine dikkat edin: çevre. Bu değişken genişleme anlamına geliyordu (öncül sadece $1
, $2
... konumsal parametrelere sahipti ). Bourne kabuğu ayrıca komut değiştirmeyi de başlattı.
Bourne kabuğunun başka kötü tasarım karar muhtemelen Thompson kabuğu ile geriye dönük uyumluluk için değişkenler ve komut ikame (genişlemesi üzerine globbing (ve bölme) yapılmasıdır echo $1
hala çağırmak olacaktır /etc/glob
halinde $1
ihtiva joker (daha ön-işlemci makro genişleme gibi orada, genişletilmiş değerde olduğu gibi kabuk kodu olarak tekrar ayrıştırıldı)).
Eşleşmeyen globların başarısız olması örneğin:
pattern='a.*b'
grep $pattern file
Komutu başarısız olur ( a.whateverb
geçerli dizinde bazı dosyalar yoksa ). csh
(aynı zamanda değişken genişleme üzerine globbing de uygular) bu durumda komutta başarısız olmaz (ve içinde olduğu gibi globbing yapmamak kadar iyi olmasa da orada uyuyan bir hata bırakmaktan daha iyi olacağını iddia ediyorum zsh
).