web-dev-qa-db-fra.com

La tuyauterie ne fonctionne pas avec la commande echo

Lorsque j'exécute le script Bash suivant, je m'attends à ce qu'il imprime Hello. Au lieu de cela, il imprime une ligne vierge et se ferme.

echo 'Hello' | echo

Pourquoi piping la sortie de echo vers echo ne fonctionne-t-elle pas?

45
Elliot A.

echo affiche tous ses arguments. Il ne lit pas dans stdin. Donc, le second echo imprime tous ses arguments (aucun) et se ferme, en ignorant le Hello sur stdin.

Pour un programme qui lit son stdin et l’affiche dans stdout, utilisez cat:

$ echo Hello | cat
Hello
53
iobender

Vous ne semblez pas comprendre les pipes. Dans ce cas, on les appelle plus correctement des canaux anonymes , car ils n'ont pas de nom (il existe également des tubes nommés ). Les canaux anonymes ne fonctionnent qu'entre des processus associés, par exemple des processus avec le même parent.

Les pipes font partie du système IO résultant de la bibliothèque d'exécution C. Ces flux sont mis en mémoire tampon (il existe un Par défaut, un canal connecte simplement le tampon de sortie d’un processus au tampon d’entrée d’un autre.

Les trois premiers flux utilisés (appelés descripteurs de fichier ) sont numérotés 0, 1 et 2. Le premier, 0, est appelé entrée standard ou stdin (le nom utilisé en C). Par défaut, il est connecté au clavier, mais il peut être redirigé à l'aide du symbole < Ou par le nom du programme situé à droite d'un tuyau.

La seconde, 1, est connue sous le nom de sortie standard ou stdout. Par défaut, il est connecté à l'écran du terminal, mais peut être redirigé à l'aide du symbole > Ou du nom du programme situé à gauche d'un tuyau.

Alors:

echo 'Hello' | echo

prend la sortie standard de echo et la transmet à l'entrée standard de echo. Mais echo ne lit pas stdin! Donc rien ne se passe.

Les programmes de filtrage traitent les noms de fichiers spécifiés sur la ligne de commande. Si aucun nom de fichier n'est donné, ils lisent stdin. Les exemples incluent cat, grep et sed, mais pasecho. Par exemple:

echo 'Hello' | cat

affichera 'Bonjour', et le cat est inutile (c'est souvent le cas).

echo 'Hello' | cat file1

va ignorer la sortie de echo et simplement afficher le contenu de fichier1. Rappelez-vous que stdin n'est lu qu'en l'absence de nom de fichier.

Que pensez-vous que cela affiche?

echo 'Hello' | cat < file1 file2

et pourquoi?

Enfin, le troisième flux, 2, est appelé erreur type ou stderr, et celui-ci est sans tampon . Les pipes sont ignorés car ils ne fonctionnent qu'entre stdin et stdout. Cependant, vous pouvez rediriger stderr pour utiliser stdout (voir man dup2):

myprog 2>&1 | anotherprog

Le 2>&1 Signifie "rediriger le descripteur de fichier 2 au même endroit que le descripteur 1".

Le comportement ci-dessus est normal. Cependant, un programme peut remplacer tout cela s'il le souhaite. Il pourrait lire le descripteur de fichier 2, par exemple. J'ai omis de nombreux autres détails, y compris d'autres formes de redirection telles que la substitution de processus et ici des documents .

15
cdarke

La tuyauterie ne peut être faite que pour les commandes prenant des entrées de stdin. Mais l'écho ne prend pas de stdin. Il faudra entrer l'argument et l'imprimer. Donc, cela ne fonctionnera pas. Pour faire écho, vous pouvez faire quelque chose comme echo $(echo 'hello')

5
Rakesh Nair

C’est parce que echo (à la fois construit et /bin/echo) ne lis rien de stdin.

Utilisez cat à la place:

echo 'Hello' | cat
Hello

Ou sans tuyaux:

cat <<< 'Hello'
2
anubhava