“Rm *” çalıştırılırken “Eşleşme bulunamadı” dan nasıl kurtulur


23

Kullanarak zsh, uymayan bir desen seçerken "Eşleşme bulunamadı" mesajı alıyorumrm ve çıktıyı yönlendirirken bile .

# rm * > /dev/zero 2>&1
  zsh: no matches found: *

Bu mesajdan nasıl kurtulabilirim?


Geçerli dizindeki her şeyi silmeye mi çalışıyorsunuz? Geçerli dizin nedir?
cutrightjm

Kullanabilirsiniz setopt extended_glob(hatta düz olabilir rm * >/dev/null 2>&1) ama gerçekten ihtiyacınız olmayan bir çözüm rm *
bulmalısınız

/dev/nullO zamandan çok batan olmalısın dev/zero. Ayrıca, stderr yönlendirmenizde bir eksik var &; olmalı 2>&1.
roaima

Hata iletisi, zshkomutun kendisinin çalışma zamanı sırasında değil, komutun değerlendirilmesi sırasında oluşturulur (hata nedeniyle komut çalıştırılmaz). Buradaki çıktı yönlendirmeleri kabuğun kendisini değil, yalnızca komutun çıktısını etkiler.
Adaephon

Yanıtlar:


44

Bu davranış Zsh nomatchseçeneği tarafından denetlenir . Varsayılan olarak, bir komut satırı hiçbir şeyle eşleşmeyen bir globbing ifadesi içeriyorsa, Zsh gördüğünüz hata mesajını yazdırır ve komutu hiç çalıştırmaz. Bunu çalıştırarak devre dışı bırakabilirsiniz

setopt +o nomatch

Sonra, bir şey eşleşmeyen globbing ifadeler olduğu gibi kalacak ve bir hata iletisi alırsınız rmkullanmakta devre dışı bırakabilir ( -fyani diğer durumlarda kaldırma zorlar çünkü kötü bir fikir olsa da, nereye olmayabilir istemek).


4
Davranış ayrıca nullglobve cshnullglobseçenekleri tarafından denetlenir . Eğer nullglobayarlanır ve eşleşen dosya bulunursa, desen yerine bir hata generationg argüman listesinden kaldırılır. Komuttaki cshnullglobtüm desenlerin eşleşmemesi durumunda ayarın benzer bir etkisi vardır, bu durumda bir hata raporlanır. Not: ayar nullglobveya cshnullglobgeçersiz kılmalar nomatch. Ayrıca ayarlayabilirsiniz nullglobglob tanımlamasını kullanarak tek desenleri N: rm *(N).
Adaephon

nomatchİdeal olandan daha az, Bourne benzeri mermilerin yaptığı şey budur. Örüntü eşleşmezse, olduğu gibi rm(!) 'Ye iletilir; bu, üzerine rmbir hata verir veya daha kötüsü, *.[ch]örneğin bir örüntü için yanlış dosyayı silebilir !
Stéphane Chazelas

9

Bunun yerine ne yapmasını isterdiniz? Hiç çalıştırılmıyor rmmu (1)? *Bourne benzeri diğer mermilerde olduğu gibi gerçek bir argümanla mı çalışıyorsunuz (2)? Hiç argüman olmadan mı (3)?

  1. files=(*(N)); (($#files)) && rm -- $files. Ya (rm -- *) 2> /dev/nullda rmbu saçma olacak gerçek hataları da gizlerdi. zshHatayı atabilir, ancak rmkomut için stderr'ı geri yükleyebilirsiniz.(rm -- * 2>&3 3>&-) 3>&2 2> /dev/null
  2. emulate sh -c 'rm -- *' 2> /dev/null. Daha sonra , bu tek komut satırı için şimdi taklit shedildiği gibi, zsheşleşmeyenlik *olduğu gibi iletilir rmve rmbu *dosya olmadığı için şikayet eder . Biz bastırmak rmİçinde yapacağı gibi 'ın stderr'yi shbastırmak için bu hata mesajı, ama yine, tarafından hakiki hataları gizlemek gibi saçma olduğunu rmdoğması uğradıkları hata aksine shbir hazır geçirerek *için rm. rm -f '*'mevcut olmayan bir *dosyadan şikayetçi olmaz.emulate sh -c 'rm -f -- *'
  3. rm -- *(N). rmyine de herhangi bir argümanı geçmediğinde şikayet ederdi, yine rm -f: değil rm -f -- *(N).

Genellikle, rm -ftüm dosyaların gitmesini ve yalnızca dosyaların kaldırılamaması veya IOW rmdöndükten sonra hala orada olması durumunda hata almak istiyorsanız kullanmak istediğiniz komuttur . Ayrıca genellikle-f , bazı durumlarda kullanıcıya sorulmasını önlemek için komut dosyalarında .

Burada, rmglob eşleşmediğinde aramak yanlıştır. sh1 davranış yanlıştır. Gibi bir desen için zararsızdır *, ancak benzer bir şekilde eşleşmediğinde olduğu gibi *.[ch]geçmek dosyanın yanlışlıkla kaldırılmasına *.[ch]neden olabilir *.[ch]:

$ ls
*.[ch]  foo.txt
$ zsh -c 'rm *.[ch]'
zsh:1: no matches found: *.[ch]
$ ls
*.[ch]  foo.txt
$ sh -c 'rm *.[ch]'
$ ls
foo.txt

Bir hata ile başarısız yapılacak en mantıklı şeydir ve ne olduğunu zsh(ve fish, csh, tcsh,bash -o failglob ve orijinal Unix kabuk) yapar.

Ve bu özel durumla ilgilenmek istiyorsanız, yukarıdaki (1) örneğinde olduğu gibi glob niteleyicisi ( noglob için ) zshile kolaylaştırır . (en azından son sürümde ) , komut için örtük bir noglob yaptığı için bunu daha da kolaylaştırır . Yani, orada eşdeğer:(N)fishset

set files *
if count $files > /dev/null
  rm -f -- $files
end

Daha fazla bilgi için bkz. Nullglob neden varsayılan değil .


1 . Açıkçası sadece shBourne kabuğundan beri (1979'da Unix V7'den beri); önceki sürümleri sh(çağrı yaptılar /etc/globnerede olduğu tırnaksız joker karakterler üzerine glob adı geliyor) gibi davranacaksan yaptılar cshya zsh -o cshnullglobolduğu, /etc/globNeználkovo hiçbiri maçı olsaydı komutu iptal olur (ve en azından eğer eşleşmeyen globs bastırmak istiyorum birinin herhangi bir eşleşmesi vardı). Davranış Bourne kabuğu tarafından kırıldı .


Bence rmkabuktan değil hata mesajını almayı bekliyor . "Rm:` * '' kaldırılamıyor: Böyle bir dosya veya dizin yok "gibi bir şey.
Emmanuel

@Emmanuel, o zaman bu 2: emulate sh -c 'rm -- *'Bourne kabuğunun (buggy IMO) davranışını elde etmek için.
Stéphane Chazelas

@Stephane_Chazelas yazıldığı gibi, 2 sormadığı soruya doğru cevap :).
Emmanuel

@Emmanuel, tüm 3 soruyu cevaplayın: "Eşleşme yok" hatası nasıl kurtulur. OP'nin kodu rmhataları bastırır . Bu, eşleşen bir dosya olmadığında hatayı bastırmak için diğer kabuklarda yapacağınız bir şeydir ve bu da orijinal rm hatalarının bastırılmasına neden olur. Cevabım bunu özetliyor ve umarım zsh davranışının nasıl tercih edilebileceğini gösteriyor.
Stéphane Chazelas
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.