Comment faire passer la commande de sortie à d'autres commandes?

Exemple:

ls | echo ls | echo ne représente rien (une ligne vide, en fait). Je m'attends à ce qu'il imprime une liste de fichiers.

ls | grep 'foo' ls | grep 'foo' , d'autre part, fonctionne comme prévu (imprime des fichiers avec 'foo' à leur nom).

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

Pourquoi les canalisations fonctionnent-elles avec des commandes, mais pas avec d'autres? Comment puis-je contourner ce problème?

Il existe 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. Alors

 ls | echo 

Connecte la sortie standard de ls à l'entrée standard de l'écho. Très bien? Eh bien, echo ignore l'entrée standard et va décharger ses arguments de ligne de commande – qui ne sont pas dans ce cas – son propre stdout. La sortie: rien du tout.

Il y a quelques solutions dans ce cas. L'une consiste à utiliser une commande qui lit stdin et dumps à stdout, comme cat.

 ls | cat 

Will 'work', selon votre définition du travail.

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

 ls | xargs echo 

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

 echo $(ls) 

Fais également ce que vous voulez.

Ces deux outils sont très essentiels aux scripts shell, vous devriez apprendre les deux.

Pour l'exhaustivité, comme vous l'indiquez dans la question, l'autre moyen de base pour convertir stdin en ligne de commande est la commande de read intégrée de la coque. Il convertit les "mots" (mots tels que définis par la variable IFS ) à une variable temporelle, que vous pouvez utiliser dans n'importe quelle commande.

ls | echo ls | echo imprime juste une ligne vide car echo lit pas d'entrée; La dernière commande du pipeline est en fait un echo qui ne supprime que la ligne vide.

Généralement:

 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 

Si vous souhaitez faire echo la commande ls essayez:

 ls | xargs echo 

Cela appellera echo avec la sortie de ls .

Pourquoi ne pas simplement utiliser:

 echo `ls` 

Ou beaucoup plus sûr:

 echo "`ls -lrt`"