war*_*dva 5 linux bash while-loop
我正在分析两个脚本,其中包含一些我不理解的行为:
#/bin/bash
tijd=${1-60}
oud=`ls -l $MAIL`
while : ; do
nieuw=`ls -l $MAIL`
echo $oud $nieuw
sleep $tijd
done | { read a b rest ; echo $a ; echo $b ; echo $rest ; }
Run Code Online (Sandbox Code Playgroud)
此脚本中的while循环在一次迭代后停止.
#/bin/bash
tijd=${1-60}
oud=`ls -l $MAIL`
while : ; do
nieuw=`ls -l $MAIL`
echo $oud $nieuw
sleep $tijd
done | cat
Run Code Online (Sandbox Code Playgroud)
此脚本中的while循环是无限的.
有什么不同?我认为它与管道和括号有关,但我无法解释它.
带有readafter管道的循环在第一次迭代后终止,因为调用了SIGPIPEread信号,该信号发生在管道的 LHS 写入到其输出未被读取的管道中,因为RHS 上没有 while 循环)。我们的示例cat不会退出,因为cat 连续读取输入,而 as在读取一行后read 终止。
要理解这种行为,首先减少您的示例:
while : ; do pwd; done | { read -r line; echo $line; }
/Users/admin
Run Code Online (Sandbox Code Playgroud)
所以read在第一行之后终止。要验证此启用,pipefail请使用:
set -o pipefail
Run Code Online (Sandbox Code Playgroud)
并检查退出状态:
while : ; do pwd; done | { read -r line; echo "$line"; }
echo $?
141
Run Code Online (Sandbox Code Playgroud)
存在状态141是由于SIGPIPE.
要解决此问题,请立即更改readwhile 循环内管道的 RHS:
while : ; do pwd; sleep 5; done | { while read -r line; do echo "$line"; done; }
/Users/admin
/Users/admin
/Users/admin
Run Code Online (Sandbox Code Playgroud)
现在您将根本看不到命令退出,因为while read它不断从管道的 LHS 捕获所有数据。