109 votes

Comment diriger la sortie d'une commande vers d'autres commandes ?

Exemple :

ls | echo n'imprime rien (une ligne blanche, en fait). Je m'attendrais à ce qu'il imprime une liste de fichiers.

ls | grep 'foo' d'autre part, fonctionne comme prévu (imprime les fichiers dont le nom contient 'foo').

Ce que je fais dans ces situations est quelque chose comme : ls | while read OUT; do echo $OUT; done mais cela est plutôt lourd.

Pourquoi le tuyautage fonctionne-t-il avec certaines commandes, mais pas avec d'autres ? Comment puis-je contourner ce problème ?

153voto

Lark Points 1640

Il existe une distinction entre les arguments de la ligne de commande et l'entrée standard. Un pipe connectera la sortie standard d'un processus à l'entrée standard d'un autre. Ainsi,

ls | echo

Connecte la sortie standard de ls à l'entrée standard de echo. C'est bien, non ? Eh bien, echo ignore l'entrée standard et va déverser les arguments de sa ligne de commande - qui dans ce cas n'en sont pas - dans son propre stdout. La sortie : rien du tout.

Il existe quelques solutions dans ce cas. L'une d'elles consiste à utiliser une commande qui lit stdin et décharge stdout, comme cat.

ls | cat

Travailler, ça dépend de votre définition du travail.

Mais qu'en est-il du cas général. Ce que vous voulez vraiment, c'est convertir la sortie stdout d'une commande en arguments de ligne de commande d'une autre. Comme d'autres l'ont dit, xargs est l'outil d'aide canonique dans ce cas, lisant ses arguments de ligne de commande pour une commande depuis son stdin, et construisant des commandes à exécuter.

ls | xargs echo

Vous pouvez également convertir ceci, en utilisant la commande de substitution $()

echo $(ls)

Je ferais aussi ce que vous voulez.

Ces deux outils sont assez fondamentaux pour le scriptage Shell, vous devriez apprendre les deux.

Pour être complet, comme vous l'indiquez dans la question, l'autre moyen de base pour convertir stdin en args de ligne de commande est la fonction intégrée de Shell. read commande. Elle convertit les "mots" (les mots tels que définis par la commande IFS ) à une variable temp, que vous pouvez utiliser dans n'importe quelle commande.

20voto

cYrus Points 20338

ls | echo imprime juste une ligne vide parce que echo ne lit aucune entrée ; la dernière commande du pipeline est en fait echo qui n'imprime rien d'autre qu'une ligne blanche.

En général :

a | b

s'assure que la sortie de a deviennent l'entrée de b . Je vous suggère de lire le Pipelines section de man bash .


Si vous voulez vraiment utiliser ls y echo ensemble, voici quelques exemples (assez inutiles) :

ls | xargs -L 1 echo
echo `ls`
for i in `ls` ; do echo $i ; done

15voto

Nathan Fellman Points 8972

Si vous voulez echo le site ls essai de commande :

ls | xargs echo

Ceci appellera echo avec la sortie de ls .

3voto

Urbwzrd Points 31

Pourquoi ne pas simplement utiliser :

echo `ls`

Ou beaucoup plus sûr :

echo "`ls -lrt`"

0voto

Benny Points 121

Cela peut se faire de plusieurs façons, notamment tuyau | , STDERR 2> , xargs ou en utilisant le bouton Substitution de commande $() .

Exemple d'utilisation xargs :

ls | xargs echo

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X