有人可以解释下面的代码如何工作吗?
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 '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
两个单独的行?我似乎无法全神贯注于此...
Answers:
用这种方式重写循环可以揭示正在发生的事情:
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
命令的计算结果为false而不是true,并且循环停止(在执行身体第二次)。
1:要技术和具体,在read
内置,当传递的变量名作为参数,读取输入,分割成独立的“词”,当它遇到IFS空白(见这个问题和这篇文章)。
2:首先read
,将输入的任何额外字段塞入指定的最后一个变量的行为对许多脚本编写者而言并不直观。正如Florian Diesch的回答所说,当您认为这read
将始终(尝试)读取整行时,将变得更容易理解,并且该read
意图可在有循环或无循环的情况下使用。
while
没有发挥其正常的宗旨在这个例子中,但随后的read
命令扔我......不知怎的,我的解读是,“虽然read a b c
不假,做echo ...
”。感谢您解释它是如何工作的。昨天我遇到了这段代码,并且知道在我弄明白之前它会
read a b c
求值为true时,循环条件(read a b c
)都会运行多次。该位仅在第一时间评估为真。第二次,没有更多的输入要从管道读取,因此遇到文件结尾,导致read
返回false。(有关help read
详细信息,请参见输出的最后部分,“退出状态”,注意,在shell脚本中,零表示true,非零表示false。)如果将输入的多行传递给while read ...
,则循环主体将被执行多次。