Come sbarazzarsi di "Nessuna corrispondenza trovata" quando si esegue "rm *"


22

Usando zsh, ricevo un messaggio "Nessuna corrispondenza trovata" quando scelgo un modello che non si adatta rme che anche quando si reindirizza l'output.

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

Come posso eliminare questo messaggio?


Stai cercando di eliminare tutto nella directory corrente? Qual è la directory corrente?
cutrightjm,

Potresti usare setopt extended_glob(o anche semplicemente rm * >/dev/null 2>&1) ma davvero dovresti fare una soluzione alternativa per non averne bisogno rm *, è assolutamente pericoloso
grochmal

Dovresti davvero affondare /dev/nullpiuttosto allora dev/zero. Inoltre, nel tuo reindirizzamento stderr manca un &; dovrebbe essere 2>&1.
roaima,

Il messaggio di errore viene generato zshdurante la valutazione del comando e non durante l'esecuzione del comando stesso (a causa dell'errore il comando non viene nemmeno eseguito). I reindirizzamenti di output qui influirebbero solo sull'output del comando e non sulla shell stessa.
Adaephon,

Risposte:


42

Questo comportamento è controllato dal di Zsh nomatchopzione . Per impostazione predefinita, se una riga di comando contiene un'espressione globbing che non corrisponde a nulla, Zsh stamperà il messaggio di errore che stai vedendo e non eseguirà affatto il comando. Puoi disabilitarlo eseguendo

setopt +o nomatch

Quindi, le espressioni globbing che non corrispondono a nulla verranno lasciate così come sono e riceverai un messaggio di errore da rm(che puoi disabilitare usando -f, sebbene sia una cattiva idea poiché forzerà le rimozioni in altre situazioni in cui potresti non volere).


4
Il comportamento è anche controllato dalle opzioni nullglobe cshnullglob. Se nullglobè impostato e non viene trovato alcun file corrispondente, il modello viene rimosso dall'elenco degli argomenti anziché generare un errore. L'impostazione cshnullglobha un effetto simile a meno che tutti i pattern in un comando non abbiano corrispondenza, nel qual caso verrà segnalato un errore. Nota: impostazione nullglobo cshnullgloboverride nomatch. È inoltre possibile impostare nullglobper i singoli modelli utilizzando il qualificatore glob N: rm *(N).
Adaephon,

nomatchè tutt'altro che ideale, ecco cosa fanno le conchiglie tipo Bourne. Se il modello non corrisponde, viene passato così com'è rm(!) Su cui rmverrà generato un errore, o peggio potrebbe eliminare il file errato per un modello come *.[ch]ad esempio!
Stéphane Chazelas,

9

Cosa vorresti che facesse invece? Non eseguito rmaffatto (1)? Eseguirlo con un *argomento letterale come in altre shell di tipo Bourne (2)? Eseguirlo senza alcun argomento (3)?

  1. files=(*(N)); (($#files)) && rm -- $files. O (rm -- *) 2> /dev/nullma ciò nasconderebbe anche errori autentici con i rmquali sarebbe sciocco. Puoi scartare l' zsherrore ma ripristinare stderr per il rmcomando con(rm -- * 2>&3 3>&-) 3>&2 2> /dev/null
  2. emulate sh -c 'rm -- *' 2> /dev/null. Quindi, come in quello shche zshora viene emulato per quella singola riga di comando, la non corrispondenza *viene passata così com'è rme si rmlamenta perché quel *file non esiste. Sopprimiamo rm's stderr come si farebbe in shPer sopprimere il messaggio di errore, ma ancora una volta, questo è stupido come sarebbe nascondere veri errori di rmin contrasto con l'errore sostenute dal comportamento scorretto di shpassare un letterale *a rm. rm -f '*'non ti lamenti di un *file inesistente , quindi potresti farloemulate sh -c 'rm -f -- *'
  3. rm -- *(N). rmsi lamentano anche se quando non superato qualsiasi argomento, anche se ancora una volta, non è rm -f: rm -f -- *(N).

In genere, rm -fè il comando che si desidera utilizzare se si desidera che tutti i file scompaiano e si verifichi un errore solo se i file non possono essere rimossi o se IOW è ancora presente dopo la rmrestituzione. In genere, si desidera utilizzare anche -fnegli script per evitare che all'utente venga richiesto in alcune situazioni.

Qui, chiamare rmquando il glob non corrisponde è sbagliato. Il comportamento sh1 è sbagliato. È innocuo per uno schema come *, ma per uno simile *.[ch], passare così *.[ch]com'è quando non corrisponde potrebbe causare la *.[ch]rimozione errata del file:

$ 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

In mancanza di un errore è la cosa più sensata da fare ed è ciò che zsh(e fish, csh, tcsh, bash -o failglobe la shell di Unix originale) fa.

E se vuoi prenderti cura di quel caso speciale, rendilozsh facile con il suo (N)qualificatore glob (per noglob ) come nel caso (1) sopra. fish(almeno nella versione recente ) lo rende ancora più semplice in quanto fa un noglob implicito per il setcomando. Quindi, l'equivalente lì sarebbe:

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

Vedere Perché nullglob non è predefinito per ulteriori dettagli.


1 . A rigor di termini è solo shdalla shell Bourne (da Unix V7 nel 1979); le versioni precedenti di sh(che facevano appello /etc/globa caratteri jolly non quotati da cui deriva il nome glob ) si comportavano come csho zsh -o cshnullglob, cioè /etc/globinterrompevano il comando se nessuno dei glob avesse qualche corrispondenza (e sopprimere i glob non corrispondenti se almeno uno di loro ha avuto una corrispondenza). Il comportamento è stato rotto dalla shell Bourne.


Penso che si aspetti di ricevere il messaggio di errore rme non dalla shell. Qualcosa come "rm: impossibile rimuovere` * ': nessun file o directory simile ".
Emmanuel,

@Emmanuel, quindi sono 2: emulate sh -c 'rm -- *'per ottenere il comportamento (buggy IMO) della shell Bourne.
Stéphane Chazelas,

@Stephane_Chazelas come è scritto, 2 è la risposta giusta a una domanda che non ha posto :).
Emmanuel,

@Emmanuel, tutti e 3 rispondono alla domanda: come sbarazzarsi dell'errore "Nessuna corrispondenza". Il codice OP sopprime gli rmerrori. Questo è qualcosa che faresti in altre shell per sopprimere l'errore quando non ci sono file corrispondenti e questo causa anche la soppressione di errori rm autentici. La mia risposta lo sottolinea e spero che sia preferibile il comportamento di zsh.
Stéphane Chazelas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.