trouver - exec rm vs -delete


260

J'essaie de comprendre la différence entre ces deux commandes:

sudo find / -name .DS_Store -delete

et

sudo find / -name ".DS_Store"  -exec rm {} \;

J'ai remarqué que la execméthode est préférée. Pourquoi? Lequel est le plus sûr / plus rapide / meilleur? J'ai utilisé les deux sur mon Macbook et tout semble bien fonctionner.

Réponses:


245

-delete fonctionnera mieux car il n’a pas à générer de processus externe pour chaque fichier correspondant.

Il est possible que vous voyiez -exec rm {} \;souvent recommandé car il -deleten’existe pas dans toutes les versions de find. Je ne peux pas vérifier pour le moment mais je suis sûr d'avoir utilisé un findsans.

Les deux méthodes doivent être "sûres".

EDIT par commentaire de @doitmyway: assurez-vous que le nom correspond, puis supprimez-le, et non l'inverse (supprimer, puis faire correspondre). Sinon, tous les fichiers seront supprimés, qu’ils correspondent ou non . -À- dire, NE PAS faire ceci: find / -delete -name .DS_Store.

Une méthode courante pour éviter les frais généraux liés à la création d'un processus externe pour chaque fichier mis en correspondance est la suivante:

find / -name .DS_Store -print0 | xargs -0 rm

(mais notez qu'il y a un problème de portabilité ici aussi: toutes les versions de find n'ont pas -print0!)


2
Je vois. J'ai également lu que l'utilisation du -deletecommutateur avant -namesupprime l'arborescence de fichiers spécifiée, donc je suppose que je dois faire attention.
Oignon

8
Récemment, findvous pouvez utiliser -exec rm {} +pour supprimer tous les fichiers correspondants avec une seule rmcommande.
jimmij

3
.DS_Storene contient aucun caractère spécial, les guillemets sont donc inutiles et ne changent rien dans ce cas.
Celada

1
Fondamentalement, seuls les espaces (espaces, tabulations, peut-être d'autres) sont la seule chose qui fait qu'une chaîne sans guillemet est interprétée comme deux arguments de ligne de commande distincts, mais ce n'est pas tout ce que vous devez regretter pour décider de citer ou non. Vous devez vous préoccuper de tous les métacaractères du shell tels que ;or |ou >or <et `` et de nombreux autres qui ont une signification particulière pour le shell, sauf indication contraire.
Celada

1
@MarcoMarsala xargsprend en charge le problème de liste d'arguments de taille limitée de manière transparente en le divisant en plusieurs invocations de la commande.
Celada

27

En supposant que ce .DS_Storesoit des fichiers et non des répertoires, le moyen le plus rapide et le plus portable de le faire serait:

sudo find / -name .DS_Store -exec rm {} +

Le seul risque est de sudone pas être disponible, mais il est assez faible de nos jours.

L' -deleteoption utilisée pour exiger la recherche GNU est toujours non standard dans de nombreuses autres findimplémentations, elle n'est donc pas toujours disponible.

La commande de terminaison +au lieu d' \;optimiser fortement la execclause en n'exécutant pas la rmcommande pour chaque .DS_Storeprésent sur le système de fichiers.


16

Pour une machine telle que votre macbook, vous ne trouverez pas beaucoup de différence de performances entre les deux commandes. Cependant, si vous regardez la version -exec, vous pouvez voir une différence subtile:

sudo find / -iname ".file-to-delete"  -exec rm {} \;

Cela signifie que vous trouverez tous ces fichiers avec le nom ".file-to-delete". Cependant, cette recherche peut renvoyer des faux positifs indésirables. Lorsque vous faites quelque chose avec sudo, vous devriez être un peu plus prudent. L'avantage d'utiliser -exec rm {} est que vous pouvez passer des arguments à rm comme ceci:

sudo find / -iname "*~"  -exec rm -i {} \;

Dans cet exemple, je souhaite supprimer les fichiers de sauvegarde créés par emacs. Cependant, ce tilde pourrait se trouver dans un fichier obscur que je ne connais pas et qui pourrait être important. De plus, je veux confirmer la suppression. J'ai donc mis l'option '-i' sur la commande rm. Cela me donnera une suppression interactive.

Vous pouvez aussi affiner l'utilisation de rm pour supprimer des répertoires ainsi que des fichiers:

find /usr/local/share/ -iname "useless" -exec rm -r {} \;

En bref, l'option -exec vous donne un peu plus de contrôle sur la commande qui supprime l'élément trouvé. L'avantage est que vous utilisez un outil pour trouver les fichiers, un autre outil pour les supprimer. De plus, toutes les versions de l'utilitaire de recherche ne possèdent pas l'option -delete. Mieux vaut donc utiliser chaque outil pour son propre travail. C’est la philosophie Unix: un outil, un travail, utilisez-les ensemble pour faire ce que vous devez faire.


3
Voir aussi -ok rm {} \;à la place de -exec rm {} \;pour la confirmation interactive.
Kusalananda
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.