tl;dr :-delete
n'est pas requis par POSIX, -exec
est.
Faits
Page de manuel POSIX 1003.1 pour find
spécifie -exec
mais pas -delete
.
Cela signifie -exec
devrait fonctionner pratiquement partout. Je serais surpris de trouver find
qui a -delete
sans -exec
. L'inverse est tout à fait possible. Systèmes particulièrement légers qui utilisent busybox
ont tendance à ne fournir que des options de ligne de commande de base.
Par exemple. J'ai un OpenWRT sur un de mes routeurs et son find
comprend -exec
, il ne comprend pas -delete
.
Ne pas avoir -delete
n'est pas un gros problème quand vous avez -exec rm …
. Par contre -delete
ne peut pas remplacer -exec
en général. C'est une conception sage de permettre d'omettre -delete
d'abord.
Expérience personnelle, observations et opinions
Ce qui précède devrait être la principale raison pour laquelle -exec rm {} \;
est si largement recommandé. Le secondaire peut être un effet boule de neige. Les utilisateurs lisent des articles et des exemples, se familiarisent avec -exec
et publier leurs propres commandes (par exemple ici sur Super User). Certains d'entre eux ne connaissent peut-être même pas -delete
existe.
Quelques fois j'ai vu (ou donné) des remarques comme 'Vous pouvez utiliser -delete
Au lieu'. Et les réponses étaient du genre "Merci, je ne le savais pas". Je ne me souviens d'aucune réponse "Je sais, mais ce n'est pas POSIX".
Cela dit, j'ai tendance à mentionner -delete
chaque fois que -exec rm {} \;
apparaît. La raison est -delete
ne génère pas de nouveau processus, tandis que -exec rm {} \;
invoque un rm
séparé pour chaque fichier correspondant. Si vous ne pouvez pas utiliser -delete
alors votre prochaine pensée devrait être -exec rm {} +
qui peut supprimer plusieurs fichiers avec un seul rm
(il invoquera toujours rm
plusieurs fois si nécessaire).
Pourquoi n'est pas -exec … +
largement recommandé alors? C'est peut-être à cause de ses limites. Je peux imaginer un utilisateur inexpérimenté penser 'Cela fonctionne avec rm
, permettez-moi de l'utiliser avec mv
!' Alors -exec mv {} foo/ +
ne fonctionne pas car {}
doit être à la fin, juste avant +
. L'utilisateur est frustré et revient vers mama Windows.
-delete
recommandé est généralement en sécurité ici sur Super User, je pense. La plupart des questions spécifient les "gros" systèmes d'exploitation, find
les commandes y sont riches en options. Et même s'il y a un utilisateur dont le find
est limité, j'aurai probablement des commentaires. Il ou elle dit que la solution ne fonctionne pas pour eux et je suggère -exec rm …
expliquez plutôt le problème, etc.
Un article autonome qui recommande -delete
n'obtiendrez pas de tels commentaires. En cas de problème, un utilisateur ira simplement au lien suivant renvoyé par Google.
La différence est dans la flexibilité. Si vous utilisez -exec, vous exécutez une commande pour chaque fichier sélectionné. Si vous utilisez -exec, vous avez la possibilité d'appliquer d'autres options de recherche. Avec -delete, vous êtes limité dans l'utilisation de -prune. De plus, votre placement de -delete a un impact sur vos résultats. Voir l'extrait de documentation ci-dessous :
-delete
Delete files; true if removal succeeded. If the removal failed,
an error message is issued. If -delete fails, find’s exit status will be
nonzero (when it eventually exits). Use of -delete automatically turns on
the ‘-depth’ option.
Warnings: Don’t forget that the find command line is evaluated as an
expression, so putting -delete first will make find try to delete every-
thing below the starting points you specified. When testing a find
command line that you later intend to use with -delete, you should
explicitly specify -depth in order to avoid later surprises.
Because -delete implies -depth, you cannot usefully use -prune and -delete
together.
-exec command ;
Execute command; true if 0 status is returned. All following arguments
to find are taken to be arguments to the command until an argument
consisting of ‘;’ is encountered. The string ‘{}’ is replaced by the
current file name being processed everywhere it occurs in the arguments
to the command, not just in arguments where it is alone, as in
some versions of find. Both of these constructions might need to be escaped
(with a ‘\’) or quoted to protect them from expansion by the shell.
See the EXAMPLES section for examples of the use of the -exec option.
The specified command is run once for each matched file. The
command is executed in the starting directory. There are unavoidable security
problems surrounding use of the -exec action; you should use the -execdir
option instead.
-exec command {} +
This variant of the -exec action runs the specified command on the
selected files, but the command line is built by appending each selected
file name at the end; the total number of invocations of the command
will be much less than the number of matched files. The command line is
built in much the same way that xargs builds its command lines.
Only one instance of ‘{}’ is allowed within the command. The command is
executed in the starting directory