Cosa vorresti che facesse invece? Non eseguito rm
affatto (1)? Eseguirlo con un *
argomento letterale come in altre shell di tipo Bourne (2)? Eseguirlo senza alcun argomento (3)?
files=(*(N)); (($#files)) && rm -- $files
. O (rm -- *) 2> /dev/null
ma ciò nasconderebbe anche errori autentici con i rm
quali sarebbe sciocco. Puoi scartare l' zsh
errore ma ripristinare stderr per il rm
comando con(rm -- * 2>&3 3>&-) 3>&2 2> /dev/null
emulate sh -c 'rm -- *' 2> /dev/null
. Quindi, come in quello sh
che zsh
ora viene emulato per quella singola riga di comando, la non corrispondenza *
viene passata così com'è rm
e si rm
lamenta perché quel *
file non esiste. Sopprimiamo rm
's stderr come si farebbe in sh
Per sopprimere il messaggio di errore, ma ancora una volta, questo è stupido come sarebbe nascondere veri errori di rm
in contrasto con l'errore sostenute dal comportamento scorretto di sh
passare un letterale *
a rm
. rm -f '*'
non ti lamenti di un *
file inesistente , quindi potresti farloemulate sh -c 'rm -f -- *'
rm -- *(N)
. rm
si 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 rm
restituzione. In genere, si desidera utilizzare anche -f
negli script per evitare che all'utente venga richiesto in alcune situazioni.
Qui, chiamare rm
quando il glob non corrisponde è sbagliato. Il comportamento sh
1 è 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 failglob
e 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 set
comando. 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 sh
dalla shell Bourne (da Unix V7 nel 1979); le versioni precedenti di sh
(che facevano appello /etc/glob
a caratteri jolly non quotati da cui deriva il nome glob ) si comportavano come csh
o zsh -o cshnullglob
, cioè /etc/glob
interrompevano 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.