在阅读、grep、管道和悬挂时

Rob*_*iam 3 grep bash pipe

yes "test" | grep -m3 "test"
Run Code Online (Sandbox Code Playgroud)

印刷

test
test
test
Run Code Online (Sandbox Code Playgroud)

然后终止。也是

yes "test" | while read line; do echo $line; done | grep -m3 "test"
Run Code Online (Sandbox Code Playgroud)

yes "test" | while read line; do echo $line; done | grep -E "*" | grep -m3 "test"
Run Code Online (Sandbox Code Playgroud)

yes "test" | while read line; do echo $line | grep -E "*"; done | grep -m3 "test"
Run Code Online (Sandbox Code Playgroud)

印刷

test
test
test
Run Code Online (Sandbox Code Playgroud)

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

Jde*_*eBP 7

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

是“测试”| 读行时;做回声 $line | grep -E "*"; 完成 | grep -m3“测试”
有三个进程在运行yesgrep分别是shell程序和。但是第二个进程,即运行 shell 程序的进程,不断产生两个进一步的子进程,一个执行该进程,echo另一个运行另一个grep实例。发送的是后一个进程,SIGPIPE不是运行 shell 程序的进程。毕竟,后一个过程实际上是写入损坏的管道。

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