Linux / Commande xargs : convertir l’entrée standard en arguments
xargs lit des éléments sur l'entrée standard et construit avec eux les arguments d'une autre commande. Il sert notamment à transmettre des noms de fichiers à un programme qui les attend comme arguments. Pour des noms quelconques, associez find -print0 à xargs -0 afin de conserver les espaces, les guillemets et les retours à la ligne présents dans les noms.
Un tube ordinaire transporte des données vers l'entrée standard de la commande suivante ; il ne transforme pas automatiquement ces données en arguments. Xargs fait cette transformation et peut répartir les éléments sur plusieurs exécutions pour respecter les limites de taille des lignes de commande. Les exemples ci-dessous utilisent GNU xargs dans Bash.
Syntaxe et préparation des fichiers
producteur | xargs [options] commande [arguments-fixes…]
La commande indiquée est lancée avec ses arguments fixes, puis avec les éléments lus. Consultez man xargs pour votre système. Pour observer les frontières d'arguments sans lancer de suppression, utilisez printf avec un format fixe.
Préparez deux fichiers dans un répertoire d'exercice neuf :
xargs_lab=$(mktemp -d "$HOME/xargs-lab.XXXXXX")
cd -- "$xargs_lab"
mkdir reports
printf 'first\nsecond\n' > 'reports/two words.txt'
printf 'third\n' > 'reports/plain.txt'
Le premier nom contient un espace et le fichier comporte deux lignes ; le second comporte une ligne. Notez le chemin du répertoire pour retrouver ces données fictives. Vous pourrez quitter l'exercice avec cd "$HOME".
Voir ce que la séparation par défaut change
Sans option particulière, xargs sépare les éléments sur les blancs et les retours à la ligne, en interprétant aussi les guillemets et les barres obliques inverses de l'entrée. Une ligne ne constitue donc pas nécessairement un argument :
printf 'two words\n' | xargs -n 1 printf 'SPLIT=[%s]\n'
SPLIT=[two]
SPLIT=[words]
Ce découpage peut convenir à une liste de mots, mais pas à un chemin dont l'espace appartient au nom. Les guillemets placés autour d'un argument de printf dans la commande productrice protègent celui-ci pour le shell ; ils ne garantissent pas que xargs conservera ses frontières une fois le texte transmis dans le tube.
Préserver les noms avec le séparateur NUL
Un octet NUL sépare sans ambiguïté les noms de fichiers Unix, car un nom ne peut pas contenir cet octet. Produisez-le réellement, plutôt que d'écrire les deux caractères barre oblique inverse et zéro dans un fichier texte :
printf '%s\0' 'reports/two words.txt' 'reports/plain.txt' |
xargs -0 -r -n 1 printf 'ARG=[%s]\n'
ARG=[reports/two words.txt]
ARG=[reports/plain.txt]
Chaque chemin reste un argument. Avec -0, xargs traite aussi les guillemets et les barres obliques inverses comme des caractères ordinaires. Les deux extrémités doivent utiliser le même protocole : un producteur à lignes ordinaires suivi de xargs -0 ne constitue pas une paire correcte.
Pour obtenir les noms depuis une recherche réelle, utilisez la sortie NUL de find et de ses conditions de recherche :
find reports -type f -name '*.txt' -print0 | xargs -0 -r wc -l
Wc doit compter 2 lignes pour reports/two words.txt, 1 pour reports/plain.txt et un total de 3. L'ordre des fichiers dépend du parcours de find ; il n'est pas garanti. Pour ce petit exemple, les deux chemins tiennent dans une invocation. Pour une liste beaucoup plus grande, xargs peut créer plusieurs lots et wc peut produire un total par lot plutôt qu'un total global unique.
Éviter une exécution sur entrée vide
GNU xargs lance normalement la commande une fois même sans élément d'entrée. Comparez :
printf '' | xargs printf 'execution\n'
printf '' | xargs -r printf 'execution\n'
La première commande affiche execution, la seconde n'affiche rien. L'option -r signifie ici « ne pas exécuter si l'entrée est vide ». Vérifiez sa disponibilité et le comportement par défaut sur les autres implémentations, plutôt que de supposer qu'ils sont identiques à GNU xargs.
Cette différence compte lorsqu'une commande sans chemin explicite possède son propre comportement par défaut. Dans nos commandes find, -r évite précisément de lancer wc sans fichier si aucun nom ne correspond à la recherche.
Choisir la position des arguments avec -I
Sans -I, les éléments lus sont ajoutés à la fin des arguments fixes. Pour les placer à un endroit précis, choisissez un marqueur :
printf '%s\0' 'two words' 'plain' |
xargs -0 -r -I '{}' printf 'entree=[%s]\n' '{}'
entree=[two words]
entree=[plain]
Le marqueur est remplacé dans les arguments de la commande. Ici, le format de printf est fixe et le texte reçu reste une donnée. N'insérez pas directement un élément dans le texte d'un script sh -c : ses caractères pourraient alors être interprétés comme du code. Si un shell intermédiaire est nécessaire, gardez son script fixe et transmettez les valeurs dans des arguments positionnels correctement cités.
-I change aussi les règles de traitement et implique un fonctionnement élément par élément dans ces exemples. Ne combinez pas sans vérification les options de remplacement, de nombre de lignes et de nombre d'arguments : GNU xargs possède des règles de priorité et peut signaler des combinaisons incompatibles.
Limiter les lots et le parallélisme
-n N limite le nombre d'éléments d'entrée transmis lors d'une invocation. Il ne change pas le séparateur : le premier exemple utilisait -n 1 et a quand même coupé two words en deux éléments. Associez donc -n à -0 quand les données le demandent.
-P N autorise au plus N processus simultanés. Cet exemple lance de petits affichages avec au plus deux processus, un élément par invocation :
printf '%s\0' alpha beta gamma |
xargs -0 -r -n 1 -P 2 printf 'ITEM=[%s]\n'
Les trois éléments sont traités, mais l'ordre d'affichage n'est pas garanti. Pour des commandes réelles qui écrivent plusieurs fragments, des sorties peuvent aussi s'entrelacer. Choisissez un parallélisme borné en fonction des ressources et des destinations partagées ; un programme qui modifie le même fichier depuis plusieurs processus demande une coordination appropriée.
Vérifier les cibles avant une action réelle
Avant de remplacer printf par une commande qui modifie des fichiers, inspectez les arguments et les critères de recherche. Un séparateur NUL empêche une mauvaise découpe des noms, mais ne vérifie ni la pertinence des fichiers sélectionnés ni la stabilité d'un chemin entre sa découverte et son utilisation.
Une autre possibilité est find … -exec commande {} +, qui construit directement des arguments à partir des résultats de find. Pour une action de suppression ou de remplacement, choisissez une méthode adaptée au contexte et contrôlez d'abord une opération de lecture. N'utilisez pas une liste issue de find -print avec le découpage par défaut de xargs pour des noms quelconques.
| Option | Rôle |
|---|---|
-0 |
Lire des éléments séparés par un octet NUL. |
-r |
Avec GNU xargs, éviter l'exécution sur entrée vide. |
-n N |
Limiter les éléments d'entrée ajoutés par invocation. |
-P N |
Limiter le nombre de processus simultanés. |
-I marqueur |
Remplacer un marqueur dans les arguments fixes. |
Le manuel de GNU xargs décrit les options, leurs interactions et les codes de sortie. Contrôlez les erreurs rapportées par xargs avant d'utiliser les résultats d'un traitement automatisé ; la simple présence d'une sortie ne prouve pas que toutes les invocations ont réussi.




