Je comprends que -exec peut prendre une option + pour imiter le comportement de xargs. Y a-t-il une situation où vous « préférez une forme à une autre?

Personnellement, jai tendance à préférer la première forme, ne serait-ce que pour éviter dutiliser un tube. Je pense sûrement aux développeurs de find doit » avoir fait les optimisations appropriées. Ai-je raison?

Réponse

Vous pourriez vouloir enchaîner les appels pour trouver (une fois, quand vous avez appris, que cest possible , qui pourrait être aujourdhui). Ceci nest, bien sûr, possible que tant que vous restez dans Find. Une fois que vous dirigez vers xargs, il est hors de portée.

Petit exemple, deux fichiers a.lst et b.lst:

cat a.lst fuddel.sh fiddel.sh cat b.lst fuddel.sh 

Aucune astuce ici – simplement le fait que les deux contiennent « fuddel » mais quun seul contient « fiddel ».

Supposons que nous ne le savions pas. Nous recherchons un fichier qui correspond à 2 conditions:

find -exec grep -q fuddel {} ";" -exec grep -q fiddel {} ";" -ls 192097 4 -rw-r--r-- 1 stefan stefan 20 Jun 27 17:05 ./a.lst 

Eh bien, peut-être connaissez-vous la syntaxe de grep ou dun autre programme pour passer les deux chaînes comme condition, mais que  » Ce nest pas le point. Chaque programme qui peut retourner vrai ou faux, avec un fichier comme argument, peut être utilisé ici – grep était juste un exemple populaire.

Et notez que vous pouvez suivre find -exec avec dautres commandes de recherche, comme -ls ou -delete ou quelque chose de similaire. Notez que la suppression ne fait pas que rm (supprime les fichiers), mais aussi rmdir (supprime les répertoires) aussi.

Une telle chaîne est lue comme une combinaison ET de commandes, tant que cela nest pas spécifié autrement (à savoir avec un commutateur -or (et parens (qui doivent être masqués))).

Vous ne quittez donc pas la chaîne de recherche, ce qui est pratique. Je ne vois aucun avantage à utiliser -xargs, car vous devez être prudent en passant les fichiers, ce que la recherche na pas besoin de faire – il gère automatiquement le passage de chaque fichier comme un argument unique pour vous.

Si vous pensez avoir besoin dun masque pour les trouvailles {} accolades , nhésitez pas à consulter ma question qui demande des preuves. Mon affirmation est la suivante: « t ».

Commentaires

  • Ce message ma ouvert les yeux sur une nouvelle façon dutiliser find. Merci beaucoup!
  •  » Je ne ‘ aucun avantage à utiliser -xargs « . Ce que ‘ est la -exec façon de faire xargs -P4 pour que trois des quatre cœurs ne ‘ restent inactifs?
  • @DamianYerrick: Terminez la commande -exec pas dans « ;  » mais avec un signe + (/ plus).

Réponse

Le transfert sécurisé des noms de fichiers vers xargs nécessite que votre find prenne en charge le -print0 et votre xargs a loption correspondante pour le lire (--null ou -0). Sinon, les noms de fichiers avec unprintab Les caractères de chier, les barres obliques inverses, les guillemets ou les espaces dans le nom peuvent provoquer un comportement inattendu. En revanche, find -exec {} + fait partie de la spécification POSIX find , il est donc portable, et il est à peu près aussi sûr que find -print0 | xargs -0, et certainement plus sûr que find | xargs. Je « recommanderais de ne jamais faire find | xargs sans -print0.

Commentaires

  • Une exception notable à la portabilité de find … -exec … {} + est OpenBSD, qui na acquis cette fonctionnalité quavec la version 5.1 publiée en 2012. Tous les BSD ont -print0 pendant plusieurs années, même OpenBSD (bien quil ait également résisté à cette fonctionnalité pendant un certain temps). Solaris, en revanche, sen tient aux fonctionnalités POSIX, vous obtenez donc -exec + et pas de -print0.
  • -print0 est une douleur et bien que vous puissiez argumenter xargs --delimiter "\n" isn ‘ t équivalent, je ‘ je nai jamais utilisé le premier après avoir découvert le second .
  • Je ne ‘ voir comment -0 est plus pénible que --delimiter "\n".
  • En plus de -0, GNU xargs a besoin de -r pour éviter dexécuter la commande sil ny a ‘ aucune entrée.
  • Un autre problème de | xargs -r0 cmd est que cmd ‘ s stdin est concerné (en fonction de limplémentation xargs, il ‘ s /dev/null ou le tube.

Réponse

Si vous utilisez le formulaire -exec ... ; (en vous souvenant pour échapper le point-virgule), vous « exécutez la commande une fois par nom de fichier. Si vous utilisez -print0 | xargs -0, vous exécutez plusieurs commandes par nom de fichier. Vous devez absolument utiliser -exec +, qui place plusieurs fichiers dans une seule ligne de commande et est beaucoup plus rapide lorsquun grand nombre de fichiers est impliqué.

Un gros plus de lutilisation de xargs est la possibilité dexécuter plusieurs commandes en parallèle à laide de xargs -P. Sur les systèmes multicœurs, cela peut permettre dénormes gains de temps.

Commentaires

  • Vous vouliez dire -P au lieu de -p. Gardez à lesprit que xargs -P nest pas dans la norme POSIX, alors que find -exec {} + lest, ce qui est important si vous optez pour la portabilité.
  • @Alexios Vous navez ‘ échapper le signe plus, car il na pas de signification particulière pour le shell: find /tmp/ -exec ls "{}" + fonctionne très bien.
  • Corrent, bien sûr. Jai ‘ tout échapper après le -exec depuis si longtemps (je ‘ ma masochiste , Je ne ‘ t même utiliser des guillemets pour échapper {}, je tape toujours \{\}; don ‘ t demander), tout semble devoir être échappé maintenant.
  • @Alexios: Si vous trouvez un exemple (sauf dêtre masochiste) où le le masquage des accolades est utile, veuillez le fournir comme réponse à ma question ici – afaik cette astuce est obsolète et nest quune relique dans la page de manuel. Je ‘ n’ai jamais vu d’exemple où find /tmp/ -exec ls {} + ne ‘ fonctionnerait pas.
  • Pour moi, il sagit de la mémoire musculaire formée à lépoque de SunOS 4. Puisque je ‘ le fais depuis des années, je nai pas du tout remarqué quand bash a commencé à accepter les accolades textuellement. Je ‘ je suis presque sûr quau moins un des vieux coques que jai ‘ ai utilisé jeté des ajustements si les accolades nétaient pas ‘ t échappé.

Réponse

Concernant les performances, je pensais que -exec … + serait tout simplement meilleur car il « sagit dun outil unique faisant tout le travail mais une partie de la documentation de GNU findutil dit que -exec … + peut être moins efficace dans certains cas:

[find with -exec … +] peut être moins efficace que certaines utilisations de xargs; par exemple, xargs permet de créer de nouvelles lignes de commande pendant que la commande précédente est toujours en cours dexécution, et vous permet de spécifier un certain nombre de commandes à exécuter en parallèle. Cependant, la construction find ... -exec ... + a lavantage dune large portabilité. GNU findutils n’était pas compatible avec ‘-exec ... +’ jusqu’à la version 4.2.12 [janvier 2005] ; l’une des raisons à cela est qu’elle avait déjà l’action ‘-print0’ dans tous les cas.

Je nétais pas vraiment sûr de ce que cela signifiait alors jai demandé dans le chat où derobert la expliqué comme suit:

find pourrait probablement continuer à rechercher le prochain lot de fichiers pendant que le -exec … + est en cours dexécution, mais ce nest pas le cas.
find … | xargs … le fait, car alors la recherche est un processus différent, et elle continue en cours dexécution jusquà ce que le tampon de canal se remplisse

(Formatage par moi.)

Donc, il y a ça. Mais si les performances comptent vraiment, vous devrez faire un benchmarking réaliste ou plutôt vous demander si vous voudriez même utiliser shell pour de tels cas.

Ici, sur ce site, je pense quil vaut mieux conseiller aux gens de utilisez le formulaire -exec … + dans la mesure du possible parce que simplement parce que cest plus simple et pour les raisons mentionnées dans les autres réponses ici (par exemple gérer des noms de fichiers étranges sans avoir à réfléchir beaucoup).

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *