Lors de l'utilisation de find pour traiter des fichiers correspondant à des critères spécifiques, deux méthodes principales existent : l'option -exec et le couple find | xargs. Leur mécanisme de transmission des arguments présente des différences critiques.
L'option -exec exécute une commande pour chaque fichier trouvé individuellement. La syntaxe requiert l'utilisation de {} comme espace réservé pour le chemin du fichier et \; pour marquer la fin de la commande (le backslash échappe le point-virgule qui aurait autrement une signification dans le shell) :
$ mkdir exemples && cd exemples
$ touch "rapport_final.pdf" "note de synthèse.txt"
$ find . -type f -exec echo "Traitement:" {} \;
Traitement: ./note de synthèse.txt
Traitement: ./rapport_final.pdf
Chaque fichier déclenche une invocation séparée de la commande. Cette approche évite les erreurs liées aux noms de fichiers contenant des espaces et ne génère pas de dépassement de longueur de ligne de commande, même avec un grand nombre de fichiers.
À l'opposé, xargs agrège tous les chemins trouvés en une seule invocation de commnade via un pipe :
$ find . -type f | xargs echo "Traitement:"
Traitement: ./note ./de ./synthèse.txt ./rapport_final.pdf
Ce comportement provoque deux problèmes majeurs :
- Les espaces dans les noms de fichiers sont interprétés comme des séparateurs
- La longueur maximale de la ligne de commadne peut être dépassée avec un grand volume de fichiers
La démonstration suivante illustre la faille avec les espaces :
$ find . -type f | xargs rm
rm: impossible de supprimer './note': Aucun fichier ou dossier de ce type
rm: impossible de supprimer 'de': Aucun fichier ou dossier de ce type
$ find . -type f -exec rm {} \;
$ ls -l
total 0
xargs scinde accidentellement note de synthèse.txt en trois arguments distincts. L'option -exec reste fonctionnelle car chaque chemin est traité isolément. Toutefois, -exec génère un coût supplémentaire via des processus shell répétés, tandis que xargs optimise les appels système en regroupant les arguments.
Le choix dépend du contexte :
- Privilégiez
-execpour les noms de fichiers contenant des espaces ou les commandes nécessitant un traitement individuel - Utilisez
xargsavec-print0et-0pour les grands volumes de fichiers sans caractères spéciaux
Pour les nomms de fichiers problématiques, la combinaison find -print0 | xargs -0 résout l'ambiguïté des espaces :
$ find . -type f -print0 | xargs -0 rm