Riscrivere il loop in questo modo rivela ciò che sta accadendo:
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
Questo da come output:
(iteration beginning) a=1 b=2 c=3 4 5 6 (iteration ending)
Si noti innanzitutto che viene eseguito solo un singolo comando echo. Se fosse eseguito più di una volta, vedresti, tra le altre cose, vedere le sottostringhe (iteration beginning)e (iteration ending)stampate più di una volta.
Questo per dire che avere un whileciclo qui non sta realizzando nulla. L' readintegrato legge il testo 1 separato da spazi bianchi in ciascuna variabile specificata. L'input extra viene aggiunto alla fine dell'ultima variabile specificata. 2 Quindi variabili ae bassumono i valori 1e 2rispettivamente, mentre cassumono il valore 3 4 5 6.
Quando la condizione del ciclo ( while read a b c) viene valutata per la seconda volta, non è più disponibile alcun input dal pipe (abbiamo eseguito il piping di una sola riga di testo), quindi il readcomando restituisce false invece che true e il ciclo si interrompe (prima di eseguire corpo una seconda volta).
1 : Per essere tecnico e specifico, l' readintegrato , quando passa nomi di variabili come argomenti, legge l'input, suddividendolo in "parole" separate quando incontra spazi bianchi IFS (vedi anche questa domanda e questo articolo ).
2 : readIl comportamento di inceppare eventuali campi extra di input nell'ultima variabile specificata non è inizialmente intuitivo per molti scripter. Diventa più facile da capire se si considera che, come dice la risposta di Florian Diesch , readsarà sempre (tentato di) leggere un'intera riga - e che readsi intende sia utilizzabile con e senza un ciclo.