Reescrever 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 de eco é executado. Se 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 while
loop aqui não está realmente conseguindo nada. O read
builtin lê o texto 1 separado por espaço em branco em cada variável especificada. A entrada extra é anexada ao final da última variável especificada. 2 Assim, variáveis a
e b
assumir os valores 1
e 2
, respectivamente, enquanto que c
assume o valor 3 4 5 6
.
Quando a condição do loop ( while read a b c
) é avaliada pela segunda vez, não há mais entrada disponível no canal (nós apenas canalizamos uma única linha de texto); portanto, o read
comando é avaliado como falso em vez de verdadeiro e o loop é interrompido (antes de executar o corpo uma segunda vez).
1 : Para ser técnico e específico, o read
built-in , quando recebe nomes de variáveis como argumentos, lê a entrada, dividindo-a em "palavras" separadas quando encontra o espaço em branco do IFS (consulte também esta pergunta e este artigo ).
read
O comportamento do 2 : de obstruir qualquer campo extra de entrada na última variável especificada não é intuitivo para muitos scripts, a princípio. Torna-se mais fácil entender quando você considera que, como diz a resposta de Florian Diesch , read
sempre (tentará) ler uma linha inteira - e isso read
se destina a ser utilizável com e sem um loop.