Que voudriez-vous qu'il fasse à la place? Pas exécuté rm
du tout (1)? L'exécuter avec un *
argument littéral comme dans d'autres coquilles de type Bourne (2)? Exécutez-le sans argument du tout (3)?
files=(*(N)); (($#files)) && rm -- $files
. Ou, (rm -- *) 2> /dev/null
mais cela cacherait également de véritables erreurs rm
qui seraient idiotes. Vous pouvez ignorer l' zsh
erreur mais restaurer stderr pour la rm
commande avec(rm -- * 2>&3 3>&-) 3>&2 2> /dev/null
emulate sh -c 'rm -- *' 2> /dev/null
. Ensuite, comme dans celui sh
qui est zsh
maintenant émulé pour cette seule ligne de commande, la non-correspondance *
est transmise telle quelle rm
et se rm
plaint car ce *
fichier n'existe pas. Nous rm
supprimons le stderr de comme vous le feriez sh
pour supprimer ce message d'erreur, mais encore une fois, c'est idiot car cela cacherait de véritables erreurs par rm
opposition à l'erreur encourue par la mauvaise conduite de sh
passer un littéral *
à rm
. rm -f '*'
ne se plaindrait pas d'un *
fichier inexistant, donc vous pouvez le faireemulate sh -c 'rm -f -- *'
rm -- *(N)
. rm
se plaindrait que lorsqu'ils ne sont pas passé aucun argument, mais encore une fois, non rm -f
: rm -f -- *(N)
.
Généralement, rm -f
c'est la commande que vous souhaitez utiliser si vous voulez que tous les fichiers disparaissent et que vous obtenez une erreur uniquement si les fichiers n'ont pas pu être supprimés ou si IOW est toujours là après rm
son retour. Vous souhaitez également généralement utiliser -f
dans les scripts pour éviter que l'utilisateur ne soit invité dans certaines situations.
Ici, appeler rm
lorsque le glob ne correspond pas est faux. Le comportement sh
1 est incorrect. C'est inoffensif pour un modèle comme *
, mais pour un comme *.[ch]
, le passage *.[ch]
tel quel lorsqu'il ne correspond pas pourrait entraîner la *.[ch]
suppression du fichier par erreur:
$ 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
A défaut d'une erreur est la chose la plus sensée à faire et est ce que zsh
(et fish
, csh
, tcsh
, bash -o failglob
et le shell Unix d' origine) fait.
Et si vous voulez vous occuper de ce cas spécial, zsh
c'est facile avec son (N)
qualificatif glob (pour noglob ) comme dans le cas (1) ci-dessus. fish
(au moins dans la version récente ) le rend encore plus facile car il fait un noglob implicite pour la set
commande. Donc, l'équivalent là-bas serait:
set files *
if count $files > /dev/null
rm -f -- $files
end
Voir Pourquoi nullglob n'est-il pas par défaut pour plus de détails.
1 . À proprement parler, ce n'est que sh
depuis le shell Bourne (depuis Unix V7 en 1979); les versions antérieures de sh
(qui faisaient appel /etc/glob
à des caractères génériques sans guillemets d'où vient le nom du glob ) se comportaient comme csh
ou zsh -o cshnullglob
, c'est-à-dire /etc/glob
annuleraient la commande si aucun des globs n'avait de correspondance (et supprimeraient les globs non correspondants si au moins l'un d'eux avait un match). Le comportement a été rompu par l'obus Bourne.