Jak pozbyć się „Nie znaleziono dopasowania” podczas uruchamiania „rm *”


22

Używając zsh, otrzymuję komunikat „Nie znaleziono dopasowania” przy wyborze wzorca, który nie pasuje rmi nawet przy przekierowaniu wyjścia.

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

Jak mogę pozbyć się tej wiadomości?


Czy próbujesz usunąć wszystko z bieżącego katalogu? Jaki jest bieżący katalog?
cutrightjm

Możesz użyć setopt extended_glob(lub nawet zwykłego rm * >/dev/null 2>&1), ale naprawdę powinieneś zrobić obejście, którego nie potrzebujesz rm *, to jest zupełnie niebezpieczne
grochmal

Trzeba naprawdę być zatopienie się /dev/nullraczej wtedy dev/zero. Ponadto brakuje przekierowania stderr& ; tak powinno być 2>&1.
roaima

Komunikat o błędzie jest generowany zshpodczas oceny polecenia, a nie w czasie wykonywania samego polecenia (z powodu błędu polecenie nawet się nie uruchamia). Przekierowania danych wyjściowych wpłynęłyby tylko na dane wyjściowe polecenia, a nie na samą powłokę.
Adaephon

Odpowiedzi:


42

To zachowanie jest kontrolowane przez opcję Zshnomatch . Domyślnie, jeśli wiersz polecenia zawiera wyrażenie globbing, które nie pasuje do niczego, Zsh wydrukuje wyświetlony komunikat o błędzie i w ogóle nie uruchomi polecenia. Możesz to wyłączyć, uruchamiając

setopt +o nomatch

Następnie wyrażenia globbing, które nie pasują do niczego, pozostaną bez zmian, a otrzymasz komunikat o błędzie rm( z którego możesz wyłączyć korzystanie -f, chociaż to zły pomysł, ponieważ wymusi usunięcie w innych sytuacjach, w których możesz nie chcieć).


4
Zachowanie jest również kontrolowane przez opcje nullglobi cshnullglob. Jeśli nullglobjest ustawiony i nie znaleziono pasującego pliku, wzorzec jest usuwany z listy argumentów zamiast generowania błędu. Ustawienie cshnullglobma podobny efekt, chyba że wszystkie wzorce w poleceniu nie pasują, w takim przypadku zostanie zgłoszony błąd. Uwaga: ustawienie nullgloblub cshnullglobzastąpienie nomatch. Można również ustawić nullglobdla pojedynczych wzorów za pomocą kwalifikatora glob N: rm *(N).
Adaephon

nomatchjest mniej niż idealny, to właśnie robią muszle Bourne'a. Jeśli wzorzec nie pasuje, jest przekazywany „tak jak jest” rm(!), Co rmspowoduje błąd, lub gorzej może usunąć niewłaściwy plik dla wzorca, *.[ch]na przykład!
Stéphane Chazelas

9

Co chciałbyś zamiast tego zrobić? rmW ogóle nie działa (1)? Czy uruchomić go z dosłownym *argumentem, jak w innych powłokach podobnych do Bourne'a (2)? Uruchomić bez żadnych argumentów (3)?

  1. files=(*(N)); (($#files)) && rm -- $files. Albo (rm -- *) 2> /dev/nullale również ukryć rzeczywiste błędy przez rmco byłoby głupie. Możesz odrzucić zshbłąd, ale przywróć stderr dla rmpolecenia za pomocą(rm -- * 2>&3 3>&-) 3>&2 2> /dev/null
  2. emulate sh -c 'rm -- *' 2> /dev/null. Potem jak w shktóry zshteraz emulowane dla tej linii pojedynczej poleceń, bez dopasowywania *jest przekazywana jako-jest rmi rmskarży się, jako że *plik nie istnieje. Mamy tłumić rm„s stderr jak można zrobić w shcelu powstrzymania, że komunikat o błędzie, ale znowu, że to głupie, jak to ukryć prawdziwych błędów, rmw przeciwieństwie do błędu poniesionych przez pobycie shprzechodząc dosłownym *się rm. rm -f '*'nie narzekałby jednak na nieistniejący *plik, więc możesz to zrobićemulate sh -c 'rm -f -- *'
  3. rm -- *(N). rmbyłoby narzekać chociaż gdy nie przeszedł żadnego argumentu, choć znowu nie rm -f: rm -f -- *(N).

Ogólnie rzecz biorąc, rm -fto polecenie, którego chcesz użyć, jeśli chcesz, aby wszystkie pliki zniknęły i pojawia się błąd tylko wtedy, gdy plików nie można usunąć lub IOW nadal tam są po rmpowrocie. Zasadniczo chcesz również używać -fskryptów, aby uniknąć monitowania użytkownika w niektórych sytuacjach.

Tutaj dzwonienie, rmgdy glob nie pasuje, jest błędne. Zachowanie sh1 jest nieprawidłowe. Jest to nieszkodliwe dla takiego wzoru *, ale dla takiego jak *.[ch], przekazanie takiego *.[ch]jak jest, gdy nie pasuje, może spowodować *.[ch]pomyłkowe usunięcie pliku:

$ 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

Niepowodzeniem z błędem jest najbardziej sensowne rzeczy do zrobienia i to, co zsh(i fish, csh, tcsh, bash -o failglobi oryginalny Unix shell) robi.

A jeśli chcesz sam zająć się tym specjalnym przypadkiem, zshułatwia to jego (N)kwalifikator globalny (dla noglob ), jak w przypadku (1) powyżej. fish(przynajmniej w najnowszej wersji ) czyni to jeszcze łatwiejszym, ponieważ wykonuje ukryte polecenie dla setpolecenia. Odpowiednikiem byłoby:

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

Zobacz Dlaczego nullglob nie jest domyślny, aby uzyskać więcej informacji.


1 . Ściśle mówiąc, to dopiero shod czasu powłoki Bourne'a (od Unixa V7 w 1979 r.); wcześniejsze wersje sh(które /etc/globwzywały nieoznaczone symbole wieloznaczne, z których pochodzi nazwa globu ) zachowywały się jak cshlub zsh -o cshnullglob, to znaczy /etc/globprzerywałyby polecenie, jeśli żadna z globów nie pasowała (i tłumiłyby niepasujące globy, jeśli przynajmniej jeden z nich miał jakieś dopasowanie). Zachowanie zostało złamane przez powłokę Bourne'a.


Myślę, że spodziewa się otrzymać komunikat o błędzie z rmpowłoki, a nie z powłoki. Coś w stylu „rm: nie można usunąć` * ': Nie ma takiego pliku ani katalogu ”.
Emmanuel

@Emmanuel, to jest 2: emulate sh -c 'rm -- *'uzyskać (błędne IMO) zachowanie powłoki Bourne'a.
Stéphane Chazelas

@Stephane_Chazelas, jak jest napisane, 2 jest właściwą odpowiedzią na pytanie, którego nie zadał :).
Emmanuel

@Emmanuel, wszystkie 3 odpowiedzi na pytanie: jak pozbyć się błędu „Brak dopasowania”. Kod OP pomija rmbłędy. Jest to coś, co można zrobić w innych powłokach, aby ukryć błąd, gdy nie ma pasującego pliku, a to powoduje również tłumienie oryginalnych błędów rm. Moja odpowiedź podkreśla, że ​​i mam nadzieję, że preferowane jest zachowanie Zsh.
Stéphane Chazelas
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.