web-dev-qa-db-fra.com

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

Exemple:

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

ls | grep 'foo', en revanche, fonctionne comme prévu (imprime les fichiers avec le nom 'foo' dans leur nom).

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

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

81
Mihai Rotaru

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

ls | echo

Connecte la sortie standard de ls à l’entrée standard d’écho. Bien d'accord? Eh bien, echo ignore l’entrée standard et dumpera ses arguments en ligne de commande - qui ne sont dans ce cas aucunes - sa propre sortie standard. La sortie: rien du tout.

Il y a quelques solutions dans ce cas. La première consiste à utiliser une commande qui lit stdin et effectue un dump sur stdout, tel que cat.

ls | cat

Will 'work', en fonction de votre définition du travail.

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

ls | xargs echo

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

echo $(ls)

Feriez aussi 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'avez indiqué dans la question, l'autre méthode de base pour convertir stdin en arguments de ligne de commande est la commande intégrée read du shell. Il convertit les "mots" (les mots définis par la variable IFS) en une variable temporaire que vous pouvez utiliser dans toutes les exécutions de commandes.

115
Rich Homolka

ls | echo affiche uniquement une ligne vierge car echo ne lit aucune entrée; La dernière commande du pipeline est en fait une variable echo qui n'imprime qu'une ligne vierge.

Généralement:

a | b

s'assure que la sortie de a devienne 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 (plutôt inutiles):

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

Si vous voulez echo la commande ls essayez:

ls | xargs echo

Ceci appellera echo avec la sortie de ls.

9
Nathan Fellman

Pourquoi ne pas simplement utiliser:

echo `ls`

Ou beaucoup plus sûr:

echo "`ls -lrt`"
3
Urbwzrd