GNU/Linux >> Tutoriels Linux >  >> Linux

trouver :-exec rm {} \ ; vs. -delete - pourquoi le premier est-il largement recommandé ?

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

Linux
  1. trouver -exec cmd {} + vs | xarg

  2. trouver -exec une fonction shell sous Linux ?

  3. Pourquoi find -exec mv {} ./target/ + ne fonctionne-t-il pas ?

  4. Où se trouve le fichier d'en-tête <conio.h> sous Linux ? Pourquoi ne puis-je pas trouver <conio.h> ?

  5. adb :trouver le PID à partir du shell adb

Trouver l'ordinateur sur un réseau LAN ?

La commande Linux find Directory :Explication

Comment puis-je trouver la taille de pile maximale ?

Pourquoi le segment .bss est-il requis ?

Linux pourquoi ne puis-je pas diriger le résultat vers rm?

Comment diriger les résultats de 'find' vers mv sous Linux