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 while
ciclo qui non sta realizzando nulla. L' read
integrato 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 a
e b
assumono i valori 1
e 2
rispettivamente, mentre c
assumono 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 read
comando restituisce false invece che true e il ciclo si interrompe (prima di eseguire corpo una seconda volta).
1 : Per essere tecnico e specifico, l' read
integrato , 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 : read
Il 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 , read
sarà sempre (tentato di) leggere un'intera riga - e che read
si intende sia utilizzabile con e senza un ciclo.