Xargs

De wiki.nexiat.fr
Aller à la navigation Aller à la recherche
Fiche express
Domaine Construction de commandes à partir d'une entrée standard
Commande xargs
Contexte Transforme une liste de lignes (souvent produite par find) en arguments d'une commande, y compris quand celle-ci n'accepte pas l'entrée standard
Voir aussi Find (produire la liste de fichiers)

xargs lit des éléments sur l'entrée standard (typiquement une liste de fichiers produite par find) et les passe en arguments à une commande. C'est indispensable pour les commandes qui n'acceptent pas l'entrée standard comme source d'arguments (cp, rm, chmod…) et pour éviter de dépasser la limite de taille de la ligne de commande quand la liste est très longue.

Utilisation de base

find . -name "*.log" | xargs rm            # supprime tous les fichiers trouvés
find . -name toto | xargs -I {} cp {} /tmp # copie chaque fichier trouvé vers /tmp

-I {} définit un remplacement : {} est substitué par chaque élément lu, un par un, ce qui permet de le placer n'importe où dans la commande (y compris plusieurs fois) plutôt qu'uniquement en fin de ligne.

Gérer les noms de fichiers avec espaces ou caractères spéciaux (-0)

Par défaut, xargs découpe l'entrée sur les espaces et sauts de ligne, ce qui casse silencieusement les noms de fichiers contenant des espaces, des apostrophes ou des retours à la ligne. Le piège classique :

find . -name "* *" | xargs rm   # DANGEREUX : un nom "a b.txt" devient deux arguments "a" et "b.txt"

La solution consiste à séparer les éléments par un caractère nul (\0), qui ne peut pas apparaître dans un nom de fichier, avec le couple find -print0 / xargs -0 :

find . -name "* *" -print0 | xargs -0 rm   # sûr, quel que soit le contenu du nom

⚠️ Réflexe à prendre systématiquement dès que la liste vient de find et alimente une commande destructrice : sans -print0/-0, un nom de fichier contenant un espace, une apostrophe ou un saut de ligne peut faire exécuter la commande sur la mauvaise cible.

Nombre d'arguments par appel (-n)

Par défaut, xargs regroupe autant d'éléments que possible dans un minimum d'appels à la commande. -n force un nombre fixe d'arguments par appel :

echo {1..10} | xargs -n 2   # 5 appels, 2 arguments à chaque fois

Utile quand la commande cible n'accepte qu'un nombre limité d'arguments à la fois, ou pour forcer un traitement un par un (-n 1), équivalent dans l'esprit à -I {} mais sans nommer le remplacement.

Parallélisme (-P)

-P lance plusieurs appels de la commande en parallèle au lieu de les exécuter séquentiellement :

find . -name "*.jpg" -print0 | xargs -0 -P 4 -I {} convert {} {}.png   # 4 conversions en parallèle

-P 0 lance autant de processus que possible en parallèle (à réserver aux commandes peu coûteuses en I/O ou CPU, sous peine de saturer la machine). Combiner -n et -P permet de répartir un grand nombre d'éléments en plusieurs lots traités en parallèle.

Mise en garde sur les commandes destructrices

Comme pour find -exec/-delete (voir Find), toujours valider la sélection avant de lancer une commande destructrice sous xargs. Le plus simple est de remplacer temporairement la commande par echo pour vérifier ce qui serait exécuté :

find /tmp -iname 'msg_*' -mtime +7 -print0 | xargs -0 echo rm   # 1. on vérifie d'abord ce qui serait supprimé
find /tmp -iname 'msg_*' -mtime +7 -print0 | xargs -0 rm        # 2. seulement ensuite on exécute réellement

Voir aussi

  • Find — produire la liste de fichiers à passer à xargs