Reescrevendo o loop dessa maneira revela o que está acontecendo:
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
Isso fornece, como saída:
(iteration beginning) a=1 b=2 c=3 4 5 6 (iteration ending)
Observe primeiro que apenas um único comando echo é executado. Se ele fosse executado mais de uma vez, você veria, entre outras coisas, as substrings (iteration beginning)
e (iteration ending)
impressas mais de uma vez.
Isso significa que ter um loop while
aqui não está realmente realizando nada. O read
builtin lê o texto separado por espaço em branco 1 em cada variável especificada. A entrada extra é anexada ao final da última variável especificada. 2 Assim, as variáveis a
e b
assumem os valores 1
e 2
respectivamente, enquanto c
assume o valor 3 4 5 6
.
Quando a condição de loop ( while read a b c
) é avaliada pela segunda vez, não há mais entrada disponível do pipe (nós apenas canalizamos uma única linha de texto), então o comando read
é avaliado como falso em vez de true e o loop pára (antes de executar o corpo uma segunda vez).
1 : Para ser técnico e específico, o read
builtin , quando passou nomes de variáveis como argumentos, lê a entrada, dividindo-o em "palavras" separadas quando encontrar espaços em branco IFS (ver também esta questão e este artigo ).
2 : O comportamento de read
de bloquear qualquer campo extra de entrada na última variável especificada não é intuitivo para muitos criadores de scripts, no início. Torna-se mais fácil entender quando você considera que como a resposta de Florian Diesch diz , read
será sempre (tente) uma linha inteira - e que read
se destina a ser utilizável com e sem loop.