Genişletilmiş yıldız işareti nedeniyle hatalardan kaçınma


16

Bash'da sık sık aşağıdaki gibi döngüler kullanıyorum

for file in *.type; do 
  sommecommand "$file"; 
done;

eşleşen tüm dosyalar için bir işlem gerçekleştirmek için *.type. Çalışma dizinlerinde bu sonlu dosya bulunmazsa, yıldız işareti genişletilmez ve genellikle bazı komutların dosyayı bulamadığını söyleyen bir hata mesajı alırım. Bu hatayı önlemek için hemen birkaç yol düşünebilirim. Ancak bir koşullu eklemek çok zarif görünmüyor. Bunu başarmanın kısa ve temiz bir yolu var mı?

Yanıtlar:


20

Evet, aşağıdaki komutu çalıştırın:

shopt -s nullglob

eşleşmeyi geçersiz kılar ve hiçbir hata tetiklenmez.

  • varsayılan olarak bu davranışı istiyorsanız, komutu ~/.bashrc
  • POSIX kabuğunda boş bir glob saptamak istiyorsanız,

    for i in *.txt; do
      [ "$i" = '*.txt' ] && [ ! -e '*.txt' ] && continue
    done

Bkz. Http://mywiki.wooledge.org/NullGlob


1
Aslında bir dosyaya sahip olmanın mümkün olduğunu unutmayın *.txt. Dosyanın var olup olmadığını kontrol etmeye değer.
Chris Down

yazı buna göre düzenlenmiştir.
Gilles Quenot

@ChrisDown Cevabınızla aynı yorumun burada geçerli olduğunu unutmayın ( breakbunun yerine potansiyel olarak daha ciddi sonuçlarla continue).
Stéphane Chazelas

6

Bash'da shopt -s nullglob, eşleşme yoksa boş bir diziye genişletmek için kullanabilirsiniz .

POSIX kabuklarında nullglob, döngünüzün [ -e "$file" ] || [ -L "$file" ] || continueilk kısmı olarak geçirilen dosya adının gerçekten var olup olmadığını kontrol ederek bu sorunu önleyebilirsiniz for.


1
[ -eErişilemeyen dosyalar veya erişilemeyen veya varolmayan dosyalara simgeleri olan dosyalar için yanlış döndüreceğinden, kesinlikle eşdeğer olmayacağını unutmayın.
Stéphane Chazelas

@StephaneChazelas, sembolik noktalar hakkındaki noktaların kabul edilmesine izin verin. Peki "erişilemeyen dosyalar" dan aklınızda neler var? Hatta ben eğer chmod 0 the_file, [ -e the_file ]o başka bir şey olmalı bu yüzden hala doğru değerlendirir.
dubiousjim

1
kırık simgeleri işlemek için düzenleme gönderdi. umarım sorun olmaz.
dubiousjim

2
@dubiousjim mkdir -p x/{a,b} && chmod 444 x && echo x/* && [ -e x/a ],. x / a erişilemez ancak x okunabilir olduğundan x / * genişler.
Stéphane Chazelas

@StephaneChazelas, harika, açıkladığın için teşekkürler.
dubiousjim

4

nullglobSeçeneği olmayan mermiler için olağan teknik

set -- [*].type *.type
case $1$2 in
  '[*].type*.type') shift 2;;
  *) shift
esac
for file do
  cmd  -- "$file"
done

Ekstra [*].type, *.typegeçerli dizinde bir dosyanın bulunduğu durumu kapsamaktadır .

Şimdi, nokta dosyalarını dahil etmek istiyorsanız, bu daha karmaşık hale gelir .

Bu tekniğin birkaç yıl önce Laura Fairhead tarafından usenet üzerinde yapıldığına inanıyorum.


0

find . -name '*.type' -maxdepth 0 -exec somecommand "{}" ";"

Bu, forilmiği ve kabuğun küresini denklemden tamamen kaldırır . komutu eşleşme başına bir kez findyürütür ve -execeşleşme yoksa asla yürütülmez. -maxdepth 0Talimatını (adlandırılmış yol-Tartışmanın alt dizinler özyineleme değil bulmak .bu durumda,).

Dezavantajı, hemen hemen her Linux sisteminde (ve muhtemelen çoğu Unix de) mevcut olsa da, başka bir uygulama içermesidir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.