Fatmawati Achmad Zaenuri / Shutterstock
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 des commandes telles que echo
, rm
, et mkdir
accepter l’entrée standard comme arguments.
La commande xargs
xargs
acceptera l’entrée canalisée. 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 on ne dit pas xargs
pour travailler avec une commande spécifique, il utilisera par défaut echo
.
Nous pouvons l’utiliser pour montrer comment xargs
générera toujours une seule ligne de sortie, même à partir d’une entrée multiligne.
Si nous utilisons le -1
(lister un fichier par ligne) option 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 on passe à travers xargs
qu’est-ce qu’on obtient?
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
ajouter des paramètres à d’autres commandes.
Utilisation de xargs avec wc
On peut utiliser xargs
avoir facilement wc
compte le mots, caractères et lignes dans plusieurs fichiers.
ls *.page | xargs wc
Voici ce qui se passe:
ls
répertorie les fichiers * .page et transmet la liste àxargs
.xargs
transmet les noms de fichiers àwc
.wc
traite les noms de fichiers comme s’il les avait 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 le -p
(interactif) option pour avoir xargs
nous demander de confirmer que nous sommes heureux que cela se poursuive.
Si nous passons une chaîne de noms de fichiers à touch
, par xargs
, touch
volonté créer les fichiers pour nous.
echo 'one two three' | xargs -p touch
La commande qui va être exécutée s’affiche 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. On peut 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 le -I
(arguments initiaux) option.
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és.
Utilisons le tree
commande pour consulter les sous-répertoires du répertoire courant. le -d
(répertoire) cause tree
pour ignorer les fichiers et ne signaler 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:
- : Cela pousse le contenu du fichier directrories.txt (tous les nouveaux noms de répertoire) dans
xargs
. - : Ceci définit une «chaîne de remplacement» avec le jeton «%».
- : Cela démarre un nouveau sous-shell. le
-c
(commande) indique au shell de lire les commandes depuis la ligne de commande. - : chacun des jetons «%» sera remplacé par les noms de répertoires passés par
xargs
. leecho
la commande affichera le nom du répertoire; lamkdir
La commande créera le répertoire.
Les répertoires sont répertoriés un par un.
On peut utiliser tree
une fois de plus pour vérifier que les répertoires ont été créés.
tree -d
Copie de fichiers vers plusieurs emplacements
On peut utiliser xargs
pour nous permettre de copier des fichiers vers plusieurs emplacements avec une seule commande.
Nous allons canaliser les noms de deux répertoires dans xargs
comme paramètres d’entrée. Nous dirons xargs
pour ne transmettre qu’un de ces paramètres à la fois à la commande avec laquelle il travaille.
Dans ce cas, la commande est cp
. Donc l’effet est d’appeler cp
deux fois, à chaque fois avec l’un des deux répertoires comme paramètre de ligne de commande. le xargs
le paramètre qui permet cela est le -n
(nombre maximum) option. Nous allons en faire un.
Nous utilisons également le -v
(verbose) option avec cp
afin qu’il rapporte 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 raconte xargs
pour 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 le -print0
(nom complet, caractère nul) option.
find . -name "*.png" -type f -print0 | xargs -0 rm -v -rf "{}"
Cela se décompose comme ceci:
- :
find
va rechercher dans le répertoire actuel «.» pour les objets dont les noms correspondent à «* .png» qui sont des fichiers (type -f
). - : les noms seront terminés par un caractère nul, et les espaces et les caractères étranges seront pris en compte.
- : 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 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. tree
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épertoires sont transmis xargs
à rm
.
Les seuls changements importants entre cette commande et la commande précédente sont, le terme de recherche est le nom du répertoire le plus haut, et -type d
raconte find
pour rechercher des répertoires, pas des fichiers.
Le nom de chaque répertoire est imprimé lors de sa suppression. Nous pouvons vérifier avec tree
:
tree -d
Tous les sous-répertoires imbriqués sont supprimés.
Suppression de tous les fichiers, sauf pour un type de fichier
On peut 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, pas le nom de ceux que nous voulons supprimer.
le -not
option dit find
pour renvoyer les noms des fichiers qui correspondent au modèle de recherche. Nous utilisons le -I
(arguments initiaux) option avec xargs
une fois de plus. 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
On peut utiliser find
pour rechercher des fichiers et les transmettre xargs
à tar
, pour créer un fichier d’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.
Tous les deux xargs
et find
ont un grand nombre d’options. Nous vous encourageons à consulter leurs pages de manuel pour en savoir plus.