trouver: “-exec rm {} \;” vs. “-delete” - pourquoi l'ancien est-il largement recommandé?

4

Pourquoi est-ce que ces articles sont findtoujours utilisés -exec rm {} \;dans les cas où le texte le plus court, le plus facile à lire et à lire, -deletesemble, autant que je sache, fonctionner aussi bien?

Je me rends compte qu'il y a des cas où rm avec certaines options, comme -r -fpar exemple, on pourrait faire quelques astuces, mais il y a des tonnes d'exemples simples -exec rm {} \;dans les tutoriels partout sur le net, mais pratiquement aucun exemple d'utilisation de -delete.

Qu'est-ce que je rate? Y a-t-il une raison à cela?

Lew Rockwell Fan
la source

Réponses:

9

tl; dr: -deleten’est pas requis par POSIX, -execc’est.


Faits

Page de manuel POSIX 1003.1 pourfind spécifie -execmais pas -delete.

Cela signifie -execdevrait fonctionner pratiquement partout. Je serais surpris de constater findque cela a -deletesans -exec. Le contraire est tout à fait possible. Les systèmes particulièrement légers qui utilisent busyboxtendent à fournir uniquement des options de base en ligne de commande.

Par exemple, j'ai un OpenWRT sur l'un de mes routeurs et il findcomprend -exec, il ne comprend pas -delete.

Ne pas avoir -deleten'est pas un gros problème quand vous avez -exec rm …. D'autre part -deletene peuvent pas remplacer -execen général. C'est une conception judicieuse pour permettre l'omission en -deletepremier.


Expérience personnelle, observations et opinions

Ce qui précède devrait être la principale raison pour laquelle il -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 -execet publient leurs propres commandes (par exemple, ici sur Super User). Certains d'entre eux peuvent même ne pas savoir -deleteexiste.

Quelques fois j'ai vu (ou donné) des remarques telles que "Vous pouvez utiliser à la -deleteplace". Et les réponses étaient comme "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 -deletechaque fois que cela -exec rm {} \;apparaît. La raison en est -deleteque ne crée pas un nouveau processus, alors qu'il -exec rm {} \;appelle un distinct rmpour chaque fichier correspondant. Si vous ne pouvez pas utiliser, -deletealors votre prochaine pensée devrait être de -exec rm {} +pouvoir supprimer plusieurs fichiers avec un seul rm(même s'il en aura rmbesoin plus d'une fois).

Pourquoi n'est-il pas -exec … +largement recommandé alors? C'est peut-être à cause de ses limites. Je peux imaginer un utilisateur inexpérimenté pensant "Cela fonctionne avec rm, laissez-moi l'utiliser avec mv!" Alors -exec mv {} foo/ +ne fonctionne pas car il {}faut être à la fin, juste avant +. L'utilisateur est frustré et retourne à maman Windows.


La recommandation -deleteest généralement sans danger ici sur Super User, je pense. La plupart des questions spécifient de "gros" systèmes d'exploitation, les findcommandes sont riches en options. Et même s'il y a un utilisateur dont le nombre findest limité, j'aurai probablement des retours. Il ou elle dit que la solution ne fonctionne pas pour eux et je suggère -exec rm …plutôt, expliquer le problème, etc.

Un article autonome qui recommande de -deletene pas obtenir de tels commentaires. En cas de problème, un utilisateur accédera simplement au lien suivant renvoyé par Google.

Kamil Maciorowski
la source
C'est une exposition bien écrite. Clair, concis et pratique. Merci d'avoir pris la peine.
Lew Rockwell Fan
3

La différence réside 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, l’utilisation de -prune est restreinte. De plus, votre placement de -delete affecte 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
Michael Niño
la source
La flexibilité est certainement un point fort. Si j'utilise exec chaque fois que j'aurais utilisé delete, je pourrai éventuellement me souvenir de tous les personnages qui ressemblent à ceux de Popeye, sans avoir à chercher chaque fois que j'ai BESOIN de l'exec.
Lew Rockwell Fan
0

L'ancienne forme "largement recommandée", toujours préférée sur les systèmes sans -delete, est (en remplaçant les ellipses selon les cas):

find ... -print0 ... | xargs -0 /bin/rm ...

Cela limite les processus à deux au lieu de -execgénérer potentiellement des milliers, tout en gérant correctement les noms de fichiers avec des caractères spéciaux (alors que l'utilisation de -print0 et l'omission de -0 dans xargs permettraient de scinder les noms de fichiers de manière erronée).

Il utilise un processus de plus que findavec -deleteet présente une surcharge de communication entre processus, mais il est, comme avec -delete beaucoup plus rapide que find ... -exec /bin/rm '{}' \'dans presque tous les cas.

Alex North-Keys
la source
La question explicite est "pourquoi est-il -exec rm {} \;largement recommandé?" Votre code est sain, votre explication est correcte; mais ce n'est qu'une digression, un commentaire sur une autre façon de faire la même chose. La question ne mentionne pas xargsni ne demande des alternatives à -delete. C'est la deuxième fois que je prétends qu'une de vos réponses ne répond pas à la question. Vous venez d’améliorer votre réponse et de me convaincre que cela répond à la question. S'il vous plaît me convaincre ici aussi.
Kamil Maciorowski
Ce -exec rmn'est pas recommandé sur de nombreux systèmes, pour les raisons que j'ai données - manque de support ou volonté de limiter le nombre de processus. "largement recommandé" ne signifie pas idéal dans toutes les circonstances, et ne pas répondre à cette hypothèse semble irresponsable. Les autres réponses fournissaient déjà des détails utiles pour la question exacte; une simple reformulation du matériau cohérent n’ajoute rien. Ce que j'ai donné est complémentaire mais pertinent. Je ne suis pas ici pour remplacer les contributions à la réponse, et parfaitement bien si quelqu'un d'autre les incorpore dans une réponse autonome. N'hésitez pas à le faire vous-même.
Alex North-Keys