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 、运行该循环的
yes
shell 程序、和。管道中的最后一个进程在三个匹配后终止,关闭其输入管道的读取端。然后,管道以提前终止管道的通常方式通过 s 链终止,因为管道的每个阶段最终都会写入损坏的管道。while
grep
grep
SIGPIPE
在
是的“测试”|读取行时;回显 $line | grep -E "*";完成 | grep -m3“测试”有三个进程正在运行
yes
,分别是 shell 程序 和grep
。但是第二个进程,也就是运行 shell 程序的进程,不断地产生两个进程更远子进程,一个执行该操作echo
,另一个运行另一个grep
实例。正是后一个进程发送了SIGPIPE
和不是运行shell程序的进程。毕竟,后一个过程实际上是在写入损坏的管道。
这样做的结果是管道的第二阶段,即运行该while
循环的 shell,永远不会本身终止SIGPIPE
并继续运行,生成子管道;一遍又一遍。它看到它生成的子管道以 当然 终止,但对于运行循环的SIGPIPE
shell 来说,while
不是终止循环的原因。