Переписав цикл таким образом, вы узнаете, что происходит:
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
Это дает в качестве вывода:
(iteration beginning) a=1 b=2 c=3 4 5 6 (iteration ending)
Сначала обратите внимание, что выполняется только одна команда echo. Если бы это было работать более чем один раз, вы, помимо всего прочего, увидеть (iteration beginning)
и (iteration ending)
подстроки напечатанных более чем один раз.
Это значит, что наличие while
петли здесь ничего не значит. read
Встроенный читает разделенных пробелами текст 1 в каждой заданной переменной. Дополнительный ввод добавляется в конец последней указанной переменной. 2 Таким образом, переменные a
и b
принимают значения 1
и, 2
соответственно, c
принимают значения 3 4 5 6
.
Когда условие цикла ( while read a b c
) вычисляется во второй раз, из канала больше нет входных данных (мы передали ему только одну строку текста), поэтому read
команда оценивается как ложь вместо истины, и цикл останавливается (перед выполнением кузов второй раз).
1 : Чтобы быть техничная, встроенной , при передаче имен переменных в качестве аргументов, считывает информацию, разделив его на отдельные «слова» , когда он встречает IFS пробельные (смотри также этот вопрос и в этой статье ).read
2 : read
поведение заклинивания любых дополнительных полей ввода в последней указанной переменной, на первый взгляд, неинтуитивно для многих сценариев. Понять это становится легче, если учесть, что, как говорится в ответе Флориана Диша , read
он всегда будет (пытаться) прочитать целую строку - и это read
предназначено для использования как с циклом, так и без него.