web-dev-qa-db-fra.com

Pourquoi dois-je mettre la commande lire dans un sous-rythme lors de l'utilisation de pipeline

La commande df . Peut nous montrer quel périphérique nous sommes sur. Par example,

me@ubuntu1804:~$ df .
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/sdb1       61664044 8510340  49991644  15% /home

Maintenant, je veux obtenir la chaîne /dev/sdb1.

J'ai essayé comme ça, mais ça n'a pas fonctionné: df . | read a; read a b; echo "$a", Cette commande m'a donné une sortie vide. Mais df . | (read a; read a b; echo "$a") fonctionnera comme prévu.

Je suis un peu confus maintenant.

Je sais que (read a; read a b; echo "$a") Est un sous-vase, mais je ne sais pas pourquoi je dois faire un sous-vase ici. Comme ma compréhension, x|y Redirigera la sortie de x à l'entrée de y. Pourquoi read a; read a b; echo $a Impossible d'obtenir l'entrée mais un sous-(-shell peut-il?

5
Yves

Votre première commande

df . | read a; read a b; echo "$a"

est efficacement interprété comme

( df . | read a ) ; read a b; echo "$a"

Donc, le pipeline ne se nourrit que dans le read a commande.

Puisque vous voulez de multiples lectures du pipeline, vous devez regrouper les commandes ensemble.

Maintenant, cela n'a pas besoin d'être un sous-vase; Cela pourrait être un groupement ..

bash-4.2$ df | { read a ; read a b ; echo $a ; }
devtmpfs

Plus couramment, vous voudrez peut-être une boucle

bash-4.2$ df | while read a
> do
> read a b
> echo $a
> done
devtmpfs
tmpfs
/dev/vda3
/dev/vdb

Il y a un problème secondaire avec bash et le côté droit d'un pipeline étant exécuté un sous-riche, de sorte que le $a$b Les valeurs ne sont pas accessibles en dehors de la boucle while, mais c'est un problème différent!

2
Stephen Harris