Besoin d’enchaîner certaines commandes Linux, mais l’une d’elles n’accepte pas les entrées canalisées? xargs peut prendre la sortie d’une commande et l’envoyer à une autre commande en tant que paramètres.
Tous les utilitaires Linux standard ont trois flux de données associé avec eux. Il s’agit du flux d’entrée standard (stdin), du flux de sortie standard (stdout) et du flux d’erreur standard (stderr).
Ces flux fonctionnent avec du texte. Nous envoyons une entrée (stdin) à une commande utilisant du texte, et la réponse (stdout) est écrite dans la fenêtre du terminal sous forme de texte. Les messages d’erreur sont également écrits dans la fenêtre du terminal sous forme de texte (stderr).
L’une des grandes fonctionnalités des systèmes d’exploitation de type Linux et Unix est la possibilité de diriger la sortie stdout d’une commande vers l’entrée stdin d’une deuxième commande. La première commande ne se soucie pas que sa sortie ne va pas à une fenêtre de terminal, et la deuxième commande ne se soucie pas que son entrée ne provienne pas d’un clavier.
Bien que toutes les commandes Linux aient les trois flux standard, elles n’acceptent pas toutes le stdout d’une autre commande comme entrée dans leur stdin. Cela signifie que vous ne pouvez pas leur envoyer d’entrée.
xargs est une commande permettant de créer des pipelines d’exécution à l’aide des flux de données standard. En utilisant xargs, nous pouvons faire en sorte que des commandes telles que echo, rm et mkdir acceptent l’entrée standard comme arguments.
Table des matières
La commande xargs
xargs acceptera les entrées canalisées. Il peut également accepter l’entrée d’un fichier. xargs utilise cette entrée comme paramètres pour les commandes avec lesquelles nous lui avons demandé de travailler. Si nous ne disons pas à xargs de travailler avec une commande spécifique, il utilisera par défaut echo.
Nous pouvons utiliser cela pour démontrer comment xargs générera toujours une seule ligne de sortie, même à partir d’une entrée multiligne.
Si nous utilisons l’option -1 (lister un fichier par ligne) avec ls, nous obtenons un une seule colonne de noms de fichiers.
ls -1 ./*.sh
Cela répertorie les fichiers de script shell dans le répertoire courant.
Nous obtenons une seule colonne comme prévu. Si nous passons par des xargs, qu’obtenons-nous?
ls -1 ./*.sh | xargs
La sortie est écrite dans la fenêtre du terminal, comme un long flux de texte.
C’est cette capacité qui permet à xargs d’ajouter des paramètres à d’autres commandes.
Utilisation de xargs avec wc
Nous pouvons utiliser xargs pour que wc compte facilement les mots, caractères et lignes dans plusieurs fichiers.
ls *.page | xargs wc
Voici ce qui se passe:
ls répertorie les fichiers * .page et passe la liste à xargs.
xargs transmet les noms de fichiers à wc.
wc traite les noms de fichiers comme s’ils les avaient reçus comme des paramètres de ligne de commande.
Les statistiques de chaque fichier sont affichées avec un total global.
Utilisation de xargs avec confirmation
Nous pouvons utiliser l’option -p (interactive) pour que xargs nous demande de confirmer que nous sommes heureux que cela continue.
Si nous passons une chaîne de noms de fichiers à toucher, via xargs, le toucher sera créer les fichiers pour nous.
echo 'one two three' | xargs -p touch
La commande qui va être exécutée est affichée et xargs attend que nous répondions en tapant «y» ou «Y», ou «n» ou «N», et en appuyant sur Entrée.
Si vous appuyez simplement sur Entrée, il est traité comme «n». La commande n’est exécutée que si vous tapez «y» ou «Y».
Nous avons appuyé sur «y» et appuyé sur Entrée. Nous pouvons utiliser ls pour vérifier que les fichiers ont été créés.
ls one two three
Utilisation de xargs avec plusieurs commandes
Nous pouvons utiliser plusieurs commandes avec xargs en utilisant l’option -I (arguments initiaux).
Cette option définit une «chaîne de remplacement». Partout où le jeton de la chaîne de remplacement apparaît dans la ligne de commande, les valeurs fournies à xargs sont insérées.
Utilisons la commande tree pour regarder les sous-répertoires du répertoire courant. L’option -d (répertoire) fait que l’arborescence ignore les fichiers et ne rapporte que les répertoires.
tree -d
Il existe un seul sous-répertoire appelé «images».
Dans un fichier appelé «répertoires.txt», nous avons les noms de certains répertoires que nous souhaitons créer. Nous pouvons regarder son contenu en utilisant cat.
cat directories.txt
Nous allons l’utiliser comme données d’entrée pour xargs. La commande que nous allons utiliser est la suivante:
cat directories.txt | xargs -I % sh -c 'echo %; mkdir %'
Cela se décompose comme ceci:
cat directory.txt |: Ceci pousse le contenu du fichier directrories.txt (tous les nouveaux noms de répertoire) dans xargs.
xargs -I%: Ceci définit une «chaîne de remplacement» avec le jeton «%».
sh -c: Cela démarre un nouveau sous-shell. La commande -c (commande) indique au shell de lire les commandes depuis la ligne de commande.
‘écho %; mkdir% ‘: chacun des jetons «%» sera remplacé par les noms de répertoires passés par xargs. La commande echo affichera le nom du répertoire; la commande mkdir créera le répertoire.
Les répertoires sont répertoriés un par un.
Nous pouvons à nouveau utiliser tree pour vérifier que les répertoires ont été créés.
tree -d
Copie de fichiers vers plusieurs emplacements
Nous pouvons utiliser xargs pour nous permettre de copier des fichiers vers plusieurs emplacements avec une seule commande.
Nous allons diriger les noms de deux répertoires dans xargs comme paramètres d’entrée. Nous dirons à xargs de ne transmettre qu’un de ces paramètres à la fois à la commande avec laquelle il travaille.
Dans ce cas, la commande est cp. L’effet est donc d’appeler cp deux fois, à chaque fois avec l’un des deux répertoires comme paramètre de ligne de commande. Le paramètre xargs qui permet que cela se produise est l’option -n (nombre maximum). Nous allons en faire un.
Nous utilisons également l’option -v (verbose) avec cp pour signaler ce qui se passe.
echo ~/Backups/ ~/Documents/page-files/ | xargs -n 1 cp -v ./*.page
Les fichiers sont copiés dans les deux répertoires, un répertoire à la fois. cp signale chaque action de copie de fichier afin que nous puissions les voir se dérouler.
Suppression de fichiers dans des répertoires imbriqués
Si les noms de fichiers contiennent des espaces et des caractères étranges, tels que des caractères de nouvelle ligne, xargs ne pourra pas les interpréter correctement. Nous pouvons surmonter ce problème en utilisant l’option -0 (terminateur nul). Cela indique à xargs d’utiliser le caractère nul comme délimiteur final pour les noms de fichiers.
Nous allons utiliser find dans cet exemple. find a sa propre option pour gérer les espaces et des caractères étranges dans les noms de fichiers. C’est l’option -print0 (nom complet, caractère nul).
find . -name "*.png" -type f -print0 | xargs -0 rm -v -rf "{}"
Cela se décompose comme ceci:
trouver . -name « * .png »: find va chercher dans le répertoire courant « . » pour les objets dont les noms correspondent à «* .png» qui sont des fichiers (type -f).
-print0: les noms se termineront par un caractère nul, et les espaces et les caractères étranges seront pris en compte.
xargs -0: xargs va également considérer que les noms de fichiers sont terminés par null, et les espaces et les caractères étranges ne poseront aucun problème.
rm -v -rf “{}”: rm va être verbeux et rapporter ce qui se passe (-v). Il va être récursif (-r) et parcourir les sous-répertoires imbriqués, et supprimera les fichiers sans invite (-f). Le «{}» est remplacé par chaque nom de fichier.
Tous les sous-répertoires sont recherchés et les fichiers qui correspondent au modèle de recherche sont supprimés.
Suppression de répertoires imbriqués
Disons que nous voulons supprimer un ensemble de sous-répertoires imbriqués. l’arbre nous permettra de les voir.
tree -d
find . -name "level_one" -type d printo | xargs -o rm -v -rf "{}"
Cette commande utilisera find pour effectuer une recherche récursive dans le répertoire courant. La cible de la recherche est un répertoire appelé «level_one». Les noms de répertoire sont transmis via xargs à rm.
Les seuls changements significatifs entre cette commande et la commande précédente sont, le terme de recherche est le nom du répertoire supérieur et -type d indique à find de rechercher des répertoires, pas des fichiers.
Le nom de chaque répertoire est imprimé à mesure qu’il est supprimé. Nous pouvons vérifier avec tree:
tree -d
Tous les sous-répertoires imbriqués sont supprimés.
Suppression de tous les fichiers, à l’exception d’un type de fichier
Nous pouvons utiliser find, xargs et rm pour supprimer tous les fichiers à l’exception d’un type que nous voulons conserver. C’est un peu contre-intuitif, mais nous fournissons le nom du type de fichier que nous souhaitons conserver, pas le nom de ceux que nous voulons supprimer.
L’option -not indique à find de renvoyer les noms des fichiers qui ne correspondent pas au modèle de recherche. Nous utilisons à nouveau l’option -I (arguments initiaux) avec xargs. Cette fois, le jeton de chaîne de remplacement que nous définissons est «{}». Cela se comportera exactement de la même manière que le jeton de chaîne de remplacement que nous avons généré précédemment, qui s’est avéré être un «%».
find . -type f -not - name "*.sh" -print0 | xargs -0 -I {} rm -v {}
Nous pouvons vérifier avec ls. Les seuls fichiers restants dans le répertoire sont ceux qui correspondent au modèle de recherche «* .sh».
ls -l
Création d’un fichier archive avec Xargs
Nous pouvons utiliser find pour rechercher des fichiers et les transmettre via xargs à tar, pour créer un fichier archive.
Nous allons chercher dans le répertoire courant. Le modèle de recherche est «* .page», nous allons donc rechercher des fichiers «.page».
find ./ - name "*.page" -type f -print0 | xargs -0 -tar -cvzf page_files.tar.gz
Les fichiers sont répertoriés comme prévu, lors de la création du fichier d’archive.
Le médiateur des données
Parfois, vous avez besoin d’un petit échafaudage lorsque vous empilez des choses ensemble. xargs comble le fossé entre les commandes qui peuvent pomper des informations et les commandes qui ne sont pas conçues pour les intégrer.
Les xargs et find ont un grand nombre d’options. Nous vous encourageons à consulter leurs pages de manuel pour en savoir plus.