while read、grep、管道和挂起

while read、grep、管道和挂起
yes "test" | grep -m3 "test"

印刷

test
test
test

然后终止。也是如此

yes "test" | while read line; do echo $line; done | grep -m3 "test"

yes "test" | while read line; do echo $line; done | grep -E "*" | grep -m3 "test"

yes "test" | while read line; do echo $line | grep -E "*"; done | grep -m3 "test"

印刷

test
test
test

然后挂起。这里发生了什么?

答案1

是的“测试”|读取行时;回显 $line;完成 | grep -E“*”| grep -m3“测试”
有四个进程,分别是 running 、运行该循环的yesshell 程序、和。管道中的最后一个进程在三个匹配后终止,关闭其输入管道的读取端。然后,管道以提前终止管道的通常方式通过 s 链终止,因为管道的每个阶段最终都会写入损坏的管道。whilegrepgrepSIGPIPE

是的“测试”|读取行时;回显 $line | grep -E "*";完成 | grep -m3“测试”
有三个进程正在运行yes,分别是 shell 程序 和grep。但是第二个进程,也就是运行 shell 程序的进程,不断地产生两个进程更远子进程,一个执行该操作echo,另一个运行另一个grep实例。正是后一个进程发送了SIGPIPE不是运行shell程序的进程。毕竟,后一个过程实际上是在写入损坏的管道。

这样做的结果是管道的第二阶段,即运行该while循环的 shell,永远不会本身终止SIGPIPE并继续运行,生成子管道;一遍又一遍。它看到它生成的子管道以 当然 终止,但对于运行循环的SIGPIPEshell 来说,while不是终止循环的原因。

相关内容