Utiliser "while read ..." dans un script Linux

30

Quelqu'un pourrait-il expliquer comment fonctionne le code suivant?

echo '1 2 3 4 5 6' | while read a b c
do
  echo $c $b $a
done

Plus précisément, j'aimerais savoir pourquoi la sortie de cette boucle est 3 4 5 6 2 1 , au lieu de 3 2 1 et de 6 5 4 sur deux lignes distinctes? Je ne peux pas sembler l'envelopper ...

    
posée linuxgringo 02.04.2015 - 23:11
la source

2 réponses

38

read lit une ligne entière à partir de l'entrée standard, divise la ligne en champs et affecte ces champs aux variables données. S'il y a plus de pièces que de variables, les pièces restantes sont affectées à la dernière variable.

Dans votre cas, $a est affecté à 1 , $b à 2 et $c au 3 4 5 6 restant.

    
réponse donnée Florian Diesch 02.04.2015 - 23:27
la source
23

Réécrire la boucle de cette façon révèle ce qui se passe:

echo '1 2 3 4 5 6' | while read a b c
  do
    echo '(iteration beginning)' a="$a" b="$b" c="$c" '(iteration ending)'
  done

Cela donne en sortie:

(iteration beginning) a=1 b=2 c=3 4 5 6 (iteration ending)

Notez d'abord que seule une commande echo unique est exécutée. S'il était exécuté plus d'une fois, vous verriez, entre autres choses, les sous-chaînes (iteration beginning) et (iteration ending) imprimées plus d'une fois.

Cela veut dire qu’avoir une boucle while n’accomplit vraiment rien. Le paramètre read lit le texte séparé par des espaces 1 dans chaque variable spécifiée. Une entrée supplémentaire est ajoutée à la fin de la dernière variable spécifiée. 2 Ainsi, les variables a et b prennent respectivement les valeurs 1 et 2 , tandis que c prend la valeur 3 4 5 6 .

Lorsque la condition de la boucle ( while read a b c ) est évaluée la deuxième fois, il n’ya plus d’entrées disponibles depuis le tube (nous ne lui avons acheminé qu’une seule ligne de texte), la commande read est évaluée à false au lieu de true et la boucle s'arrête (avant même d'exécuter le corps une seconde fois).

1 : pour être technique et spécifique, le fichier read intégré , lorsqu'il reçoit les noms de variables en tant qu'arguments, lit les entrées, en le séparant en "mots" lorsqu'il rencontre les espaces IFS (voir aussi cette question et cet article ).

2 : le comportement de read de brouiller des champs d’entrée supplémentaires dans la dernière variable spécifiée n’est pas intuitif pour de nombreux scripteurs, au début. Il est plus facile de comprendre que, si la réponse de Florian Diesch le dit , read va toujours (essayer de) lire une ligne entière - et que read est destiné à être utilisable avec et sans boucle.

    
réponse donnée Eliah Kagan 02.04.2015 - 23:31
la source

Lire d'autres questions sur les étiquettes