Может ли кто-нибудь объяснить, как работает следующий код?
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
на две отдельные строки? Кажется, я не могу сосредоточиться на этом ...
read
чтения целая строка от стандартного входа, разделяет строку на поля и присваивает это поля данным переменным. Если существует больше частей, чем переменные, остающиеся части присвоены последней переменной.
В Вашем случае $a
присвоен 1
, $b
присвоен 2
и $c
оставление 3 4 5 6
.
Перезапись цикла, этот путь показывает то, что происходит:
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)
Заметьте сначала, что только единственная команда эха выполняется. Если бы это было выполнено несколько раз, то Вы, среди прочего, видели бы (iteration beginning)
и (iteration ending)
подстроки распечатаны несколько раз.
Это должно сказать это имеющее a while
цикл здесь ничего действительно не выполняет. read
встроенные чтения разделенный от пробела text1 в каждую указанную переменную. Дополнительный вход добавляется в конец последней переменной, указанной 2 Таким образом переменные a
и b
возьмите значения 1
и 2
соответственно, в то время как c
берет значение 3 4 5 6
.
Когда условие цикла (while read a b c
) оценен во второй раз, там больше не вводится доступный от канала (мы только передали его по каналу одна строка текста), таким образом, read
команда оценивает ко лжи вместо истинного и остановок цикла (перед когда-либо выполнять тело во второй раз).
1: Быть техническим и конкретным, read
встроенный, когда переданные имена переменной как аргументы, вход чтений, разделяя его на отдельные "слова", когда это встретится с пробелом IFS (см. также этот вопрос и эту статью).
2: read
поведение запихивания любых дополнительных полей входа в последнюю указанную переменную неинтуитивно многим сценаристам, сначала. Становится легче понять, когда Вы полагаете, что, поскольку в ответе Florian Diesch говорится, read
будет всегда (попробовать к), читает целую строку - и это read
предназначается, чтобы быть применимым и с и без цикла.