So entfernen Sie "No match found" (Keine Übereinstimmung gefunden), wenn Sie "rm *" ausführen

21

Unter Verwendung von zshwird die Meldung "Keine Übereinstimmung gefunden" angezeigt, wenn ein Muster ausgewählt wird, das nicht zu dem Muster passt, rmund das auch, wenn die Ausgabe umgeleitet wird.

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

Wie kann ich diese Nachricht loswerden?

user123456
quelle
Versuchen Sie, alles im aktuellen Verzeichnis zu löschen? Was ist das aktuelle Verzeichnis?
Cutrightjm
Sie könnten nutzen setopt extended_glob(oder sogar Ebene rm * >/dev/null 2>&1) , aber eigentlich sollte man eine Abhilfe machen nicht brauchen rm *, das ist geradezu gefährlich
grochmal
Du solltest /dev/nulllieber dann wirklich untergehen dev/zero. Außerdem fehlt in Ihrer stderr- Umleitung ein &; es sollte sein 2>&1.
Roaima
Die Fehlermeldung wird von zshwährend der Auswertung des Befehls und nicht während der Laufzeit des Befehls selbst generiert (aufgrund des Fehlers wird der Befehl nicht einmal ausgeführt). Die Ausgabeumleitungen hier wirken sich nur auf die Ausgabe des Befehls und nicht auf die Shell selbst aus.
Adaephon

Antworten:

41

Dieses Verhalten wird durch die nomatchOption von Zsh gesteuert . Wenn eine Befehlszeile einen Globbing-Ausdruck enthält, der mit nichts übereinstimmt, gibt Zsh standardmäßig die angezeigte Fehlermeldung aus und führt den Befehl überhaupt nicht aus. Sie können dies deaktivieren, indem Sie ausführen

setopt +o nomatch

Globbing-Ausdrücke, die mit nichts übereinstimmen, bleiben unverändert und es wird eine Fehlermeldung angezeigt rm(die Sie mit deaktivieren können -f, obwohl dies eine schlechte Idee ist, da sie in anderen Situationen, in denen dies möglicherweise nicht der Fall ist, das Entfernen erzwingen möchte).

Stephen Kitt
quelle
4
Das Verhalten wird auch über die Optionen nullglobund gesteuert cshnullglob. Wenn nullglobgesetzt und keine passende Datei gefunden wird, wird das Muster aus der Argumentliste entfernt, anstatt einen Fehler zu generieren. Die Einstellung cshnullglobhat einen ähnlichen Effekt, es sei denn, alle Muster in einem Befehl stimmen nicht überein. In diesem Fall wird ein Fehler gemeldet. Hinweis: Einstellen nullgloboder cshnullglobÜberschreiben nomatch. Sie können auch einstellen , nullglobindem Sie die glob Qualifikation für einzelne Muster N: rm *(N).
Adaephon
nomatchist weniger als ideal, das tun Bourne-ähnliche Muscheln. Wenn das Muster nicht übereinstimmt, wird es so übergeben, wie es ist rm(!), rmWoraufhin ein Fehler ausgegeben wird, oder schlimmer noch, es könnte die falsche Datei für ein Muster wie *.[ch]zum Beispiel löschen !
Stéphane Chazelas
9

Was soll es stattdessen tun? Überhaupt nicht ausgeführt rm(1)? Führen Sie es mit einem wörtlichen *Argument wie in anderen Bourne-ähnlichen Shells aus (2)? Führen Sie es ohne Argumente aus (3)?

  1. files=(*(N)); (($#files)) && rm -- $files. Oder (rm -- *) 2> /dev/nullaber das würde auch echte Irrtümer verbergen, rmdie albern wären. Sie könnten den zshFehler verwerfen , aber stderr für den rmBefehl mit wiederherstellen(rm -- * 2>&3 3>&-) 3>&2 2> /dev/null
  2. emulate sh -c 'rm -- *' 2> /dev/null. Dann wird, wie in dem Beispiel, shdas zshjetzt für diese einzelne Befehlszeile emuliert wurde, die Nichtübereinstimmung so *wie sie ist an übergeben rmund rmbeschwert sich, da diese *Datei nicht vorhanden ist. Wir unterdrücken rm's stderr, wie Sie es tun würden sh, um diese Fehlermeldung zu unterdrücken, aber das ist auch albern, da es echte Fehler rmim Gegensatz zu dem Fehler, der durch das Fehlverhalten beim shÜbergeben eines Literal *an entsteht, verbergen würde rm. rm -f '*'Ich würde *mich jedoch nicht über eine nicht vorhandene Datei beschweren , also könnten Sie dies tunemulate sh -c 'rm -f -- *'
  3. rm -- *(N). rmobwohl würden sich beschweren , wenn kein Argument übergeben, obwohl auch hier nicht rm -f: rm -f -- *(N).

Allgemein, rm -f ist der Befehl, den Sie verwenden möchten, wenn alle Dateien gelöscht werden sollen und nur dann eine Fehlermeldung angezeigt wird, wenn Dateien nicht entfernt werden konnten oder IOW nach rmder Rückkehr noch vorhanden ist. Sie möchten -fim Allgemeinen auch in Skripten verwenden, um zu vermeiden, dass der Benutzer in bestimmten Situationen dazu aufgefordert wird.

Hier ist das Aufrufen, rmwenn der Glob nicht übereinstimmt, falsch. Das sh1- Verhalten ist falsch. Es ist harmlos für ein Muster wie *, aber für eines wie*.[ch] vorbei , *.[ch]wie sie ist , wenn sie nicht dazu führen , übereinstimmen könnten die*.[ch] - Datei versehentlich entfernt werden:

$ 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

Mit einem Fehler zu scheitern, ist das sinnvollste und das, was zu tun ist zsh (und fish, csh, tcsh, bash -o failglobund der ursprünglich Unix - Shell) der Fall ist.

Und wenn Sie sich um diesen speziellen Fall kümmern möchten, zshmachen Sie es sich mit dem (N)Glob-Qualifier (für noglob ) wie in Fall (1) oben leicht . fish(zumindest in der neuesten Version ) macht es noch einfacher, als es ein implizites tut Noglob tut für den setBefehl . Das Äquivalent wäre also:

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

Sehen Warum ist nullglob nicht Standard? .


1 . Genau genommen ist es erst shseit der Bourne-Shell (seit Unix V7 im Jahr 1979); frühere Versionen von sh(die nicht /etc/globzitierte Platzhalter verwendeten, von denen der Glob- Name stammt) verhielten sich wie cshoder zsh -o cshnullglob, /etc/globdh sie brachen den Befehl ab, wenn keiner der Globs übereinstimmte (und unterdrückten die nicht übereinstimmenden Globs, wenn zumindest einer von ihnen hatte ein Streichholz). Das Verhalten wurde von der Bourne-Shell unterbrochen .

Stéphane Chazelas
quelle
Ich denke, dass er erwartet, die Fehlermeldung von rmund nicht von der Shell zu erhalten. So etwas wie "rm: * kann nicht entfernt werden: Keine solche Datei oder kein solches Verzeichnis".
Emmanuel
@Emmanuel, dann ist das 2: emulate sh -c 'rm -- *'um das (fehlerhafte IMO) Verhalten der Bourne-Shell zu erhalten.
Stéphane Chazelas
@Stephane_Chazelas, wie es geschrieben steht, 2 ist die richtige Antwort auf eine Frage, die er nicht gestellt hat :).
Emmanuel
@ Emmanuel, alle 3 beantworten die Frage: Wie der "No Match" -Fehler beseitigt wird. Der OP-Code unterdrückt die rmFehler. Das ist etwas, was Sie in anderen Shells tun würden, um den Fehler zu unterdrücken, wenn es keine passende Datei gibt und das auch die Unterdrückung von echten rm-Fehlern verursacht. Meine Antwort umreißt dies und zeigt hoffentlich, wie zsh-Verhalten vorzuziehen ist.
Stéphane Chazelas