web-dev-qa-db-fra.com

Comment se débarrasser de «Aucune correspondance trouvée» lors de l'exécution de «rm *»

En utilisant zsh, j'obtiens un message "Aucune correspondance trouvée" lorsque je choisis un modèle qui ne correspond pas à rm et cela même lorsque je redirige la sortie.

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

Comment puis-je me débarrasser de ce message?

28
user123456

Ce comportement est contrôlé par Zsh nomatch option . Par défaut, si une ligne de commande contient une expression de globalisation qui ne correspond à rien, Zsh affichera le message d'erreur que vous voyez et n'exécutera pas la commande du tout. Vous pouvez désactiver cela en exécutant

setopt +o nomatch

Ensuite, les expressions globales qui ne correspondent à rien seront laissées telles quelles et vous obtiendrez un message d'erreur de rm (que vous pouvez désactiver à l'aide de -f, bien que ce soit une mauvaise idée car cela forcera les suppressions dans d'autres situations où vous ne voudrez peut-être pas).

52
Stephen Kitt

Que voudriez-vous qu'il fasse à la place? Ne pas exécuter rm du tout (1)? L'exécuter avec un argument littéral * Comme dans d'autres shells de type Bourne (2)? Exécutez-le sans argument du tout (3)?

  1. files=(*(N)); (($#files)) && rm -- $files. Ou (rm -- *) 2> /dev/null Mais cela masquerait également les vraies erreurs par rm ce qui serait idiot. Vous pouvez ignorer l'erreur zsh mais restaurer stderr pour la commande rm avec (rm -- * 2>&3 3>&-) 3>&2 2> /dev/null
  2. emulate sh -c 'rm -- *' 2> /dev/null. Ensuite, comme dans sh qui zsh maintenant émulé pour cette seule ligne de commande, le * Non correspondant est passé tel quel à rm et rm se plaint car ce fichier * n'existe pas. Nous supprimons le stderr de rm comme vous le feriez dans sh pour supprimer ce message d'erreur, mais encore une fois, c'est idiot car cela cacherait les erreurs réelles par rm par opposition à l'erreur encourue par la mauvaise conduite de sh en passant un littéral * à rm. rm -f '*' Ne se plaindrait pas d'un fichier * Inexistant, vous pouvez donc faire emulate sh -c 'rm -f -- *'
  3. rm -- *(N). rm se plaindrait si aucun argument n'était passé, mais encore une fois, pas rm -f: rm -f -- *(N).

En règle générale, rm -f Est la commande que vous souhaitez utiliser si vous souhaitez que tous les fichiers disparaissent et que vous obtenez une erreur uniquement si les fichiers n'ont pas pu être supprimés ou si l'IOW est toujours là après le retour de rm. 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 incorrect. Le sh1 le comportement est mauvais. C'est inoffensif pour un modèle comme *, Mais pour un modèle comme *.[ch], Passer *.[ch] Tel quel lorsqu'il ne correspond pas pourrait provoquer le fichier *.[ch] à supprimer 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

Un échec avec une erreur est la chose la plus raisonnable à faire et c'est ce que zsh (et fish, csh, tcsh, bash -o failglob Et le shell Unix d'origine).

Et si vous voulez vous occuper de ce cas particulier, zsh vous facilite la tâche avec son qualificatif glob (N) (Pour noglob ) comme dans le cas (1) ci-dessus. fish (au moins dans version récente ) le rend encore plus facile car il fait un noglob implicite pour le set commande. Donc, l'équivalent là-bas serait:

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

Voir Pourquoi nullglob n'est pas par défaut pour plus de détails.


1. À proprement parler, ce n'est que sh depuis le Bourne Shell (depuis Unix V7 en 1979); les versions antérieures de sh (qui appelaient /etc/glob sur des caractères génériques non cités, d'où vient le nom glob ) se comporter comme csh ou zsh -o cshnullglob, c'est-à-dire que /etc/glob annulerait la commande si aucun des globes n'avait de correspondance (et supprimerait les globes non correspondants si au moins l'un des ils avaient n'importe quel match). Le comportement a été rompu par le Bourne Shell.

10
Stéphane Chazelas