Может кто-нибудь объяснить, как работает следующий код?
echo '1 2 3 4 5 6' | while read a b c
do
echo $c $b $a
done
В частности, я хотел бы знать, почему вывод этого цикла 3 4 5 6 2 1
, а не 3 2 1
и 6 5 4
на две отдельные строки? Я не могу обернуться вокруг этого ...
Переписав цикл таким образом, вы узнаете, что происходит:
Это дает в качестве вывода:
Сначала обратите внимание, что выполняется только одна команда 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
предназначено для использования как с циклом, так и без него.источник
while
в этом примере это не служило своей обычной цели, но затемread
команда отбросила меня ... Каким-то образом я интерпретировал это как "покаread a b c
не ложь, делайecho ...
". Спасибо за объяснение, как это действительно работает. Я вчера натолкнулся на этот код и знал, что он будет беспокоить меня, пока я не разобрался в этом ... lolread a b c
истинно, и условие цикла (read a b c
) не запускать более чем один раз. Бит только в первый раз оценивается как истина . Во второй раз больше нет входных данных для чтения из канала, поэтому встречается конец файла , в результате чегоread
возвращается false . (Подробности см. В последнем разделе выходных данныхhelp read
«Состояние выхода», отметив, что в сценариях оболочки ноль означает «истина», а ненулевой - «ложь».) Если вы передадите более одной строки вводаwhile read ...
, тело цикла будет исполняться несколько раз.