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 whileloop aqui não está realmente conseguindo nada. O readbuiltin 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 ae bassumir os valores 1e 2, respectivamente, enquanto que cassume 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 readcomando é 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 readbuilt-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 ).
readO 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 , readsempre (tentará) ler uma linha inteira - e isso readse destina a ser utilizável com e sem um loop.