Unter Verwendung von zsh
wird die Meldung "Keine Übereinstimmung gefunden" angezeigt, wenn ein Muster ausgewählt wird, das nicht zu dem Muster passt, rm
und das auch, wenn die Ausgabe umgeleitet wird.
# rm * > /dev/zero 2>&1
zsh: no matches found: *
Wie kann ich diese Nachricht loswerden?
setopt extended_glob
(oder sogar Ebenerm * >/dev/null 2>&1
) , aber eigentlich sollte man eine Abhilfe machen nicht brauchenrm *
, das ist geradezu gefährlich/dev/null
lieber dann wirklich untergehendev/zero
. Außerdem fehlt in Ihrer stderr- Umleitung ein&
; es sollte sein2>&1
.zsh
wä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.Antworten:
Dieses Verhalten wird durch die
nomatch
Option 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ührenGlobbing-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).quelle
nullglob
und gesteuertcshnullglob
. Wennnullglob
gesetzt und keine passende Datei gefunden wird, wird das Muster aus der Argumentliste entfernt, anstatt einen Fehler zu generieren. Die Einstellungcshnullglob
hat einen ähnlichen Effekt, es sei denn, alle Muster in einem Befehl stimmen nicht überein. In diesem Fall wird ein Fehler gemeldet. Hinweis: Einstellennullglob
odercshnullglob
Überschreibennomatch
. Sie können auch einstellen ,nullglob
indem Sie die glob Qualifikation für einzelne MusterN
:rm *(N)
.nomatch
ist weniger als ideal, das tun Bourne-ähnliche Muscheln. Wenn das Muster nicht übereinstimmt, wird es so übergeben, wie es istrm
(!),rm
Woraufhin ein Fehler ausgegeben wird, oder schlimmer noch, es könnte die falsche Datei für ein Muster wie*.[ch]
zum Beispiel löschen !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)?files=(*(N)); (($#files)) && rm -- $files
. Oder(rm -- *) 2> /dev/null
aber das würde auch echte Irrtümer verbergen,rm
die albern wären. Sie könnten denzsh
Fehler verwerfen , aber stderr für denrm
Befehl mit wiederherstellen(rm -- * 2>&3 3>&-) 3>&2 2> /dev/null
emulate sh -c 'rm -- *' 2> /dev/null
. Dann wird, wie in dem Beispiel,sh
daszsh
jetzt für diese einzelne Befehlszeile emuliert wurde, die Nichtübereinstimmung so*
wie sie ist an übergebenrm
undrm
beschwert sich, da diese*
Datei nicht vorhanden ist. Wir unterdrückenrm
's stderr, wie Sie es tun würdensh
, um diese Fehlermeldung zu unterdrücken, aber das ist auch albern, da es echte Fehlerrm
im Gegensatz zu dem Fehler, der durch das Fehlverhalten beimsh
Übergeben eines Literal*
an entsteht, verbergen würderm
.rm -f '*'
Ich würde*
mich jedoch nicht über eine nicht vorhandene Datei beschweren , also könnten Sie dies tunemulate sh -c 'rm -f -- *'
rm -- *(N)
.rm
obwohl würden sich beschweren , wenn kein Argument übergeben, obwohl auch hier nichtrm -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 nachrm
der Rückkehr noch vorhanden ist. Sie möchten-f
im Allgemeinen auch in Skripten verwenden, um zu vermeiden, dass der Benutzer in bestimmten Situationen dazu aufgefordert wird.Hier ist das Aufrufen,
rm
wenn der Glob nicht übereinstimmt, falsch. Dassh
1- 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:Mit einem Fehler zu scheitern, ist das sinnvollste und das, was zu tun ist
zsh
(undfish
,csh
,tcsh
,bash -o failglob
und der ursprünglich Unix - Shell) der Fall ist.Und wenn Sie sich um diesen speziellen Fall kümmern möchten,
zsh
machen 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 denset
Befehl . Das Äquivalent wäre also:Sehen Warum ist nullglob nicht Standard? .
1 . Genau genommen ist es erst
sh
seit der Bourne-Shell (seit Unix V7 im Jahr 1979); frühere Versionen vonsh
(die nicht/etc/glob
zitierte Platzhalter verwendeten, von denen der Glob- Name stammt) verhielten sich wiecsh
oderzsh -o cshnullglob
,/etc/glob
dh 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 .quelle
rm
und nicht von der Shell zu erhalten. So etwas wie "rm: * kann nicht entfernt werden: Keine solche Datei oder kein solches Verzeichnis".emulate sh -c 'rm -- *'
um das (fehlerhafte IMO) Verhalten der Bourne-Shell zu erhalten.rm
Fehler. 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.