2010-09-16 13:40:08 +0000 2010-09-16 13:40:08 +0000
88
88

Comment transmettre la sortie d'une commande à 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', en revanche, fonctionne comme prévu (il imprime les fichiers avec “foo” dans leur nom).

Ce que je fais dans ces situations, c'est un peu comme : ls | while read OUT; do echo $OUT; done mais c'est assez lourd.

Pourquoi la tuyauterie fonctionne-t-elle avec certaines commandes, mais pas avec d'autres ? Comment puis-je contourner ce problème ?

Réponses (4)

123
123
123
2010-09-16 14:16:59 +0000

Il y a une distinction entre les arguments de la ligne de commande et l'entrée standard. Un tuyau reliera 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 l'écho. C'est bien, non ? Eh bien, echo ignore l'entrée standard et videra ses arguments de ligne de commande - qui ne sont pas dans ce cas - sur sa propre sortie standard. La sortie : rien du tout.

Il y a quelques solutions dans ce cas. L'une d'entre elles consiste à utiliser une commande qui lit stdin et envoie les arguments à stdout, comme par exemple cat.

ls | cat

Fonctionnera, selon votre définition du travail.

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

ls | xargs echo

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

echo $(ls)

ferait également ce que vous voulez.

Ces deux outils sont assez fondamentaux pour les scripts 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 commande read intégrée au shell. Elle convertit les “mots” (mots définis par la variable IFS) en une variable temp, que vous pouvez utiliser dans n'importe quelle exécution de la commande.

19
19
19
2010-09-16 13:54:37 +0000

ls | echo n'imprime qu'une ligne blanche 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 devient l'entrée de b. Je vous suggère de lire la section Pipelines de man bash.


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

ls | xargs -L 1 echo
echo `ls`
for i in `ls` ; do echo $i ; done
13
13
13
2010-09-16 14:03:04 +0000

Si vous voulez echo la commande ls essayez :

ls | xargs echo

Cela appellera echo avec la sortie de ls.

3
3
3
2011-11-09 09:48:27 +0000

Pourquoi ne pas simplement utiliser :

echo `ls`

Ou beaucoup plus sûr :

echo "`ls -lrt`"