如果true退出,该管的读取端是封闭的,而是yes继续尝试写入到写边。这种情况称为“中断管道”,它导致内核向发送SIGPIPE信号yes。由于yes对此信号无特殊要求,它将被杀死。如果忽略该信号,则其write调用将失败,并显示错误代码EPIPE。必须这样做的程序必须注意EPIPE并停止编写,否则它们将陷入无限循环。
如果执行strace yes | true1,则可以看到内核为两种可能性做准备:
write(1, "y\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\n"..., 4096) = -1 EPIPE (Broken pipe)
--- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=17556, si_uid=1000} ---
+++ killed by SIGPIPE +++
strace正在通过调试器API监视事件,该API首先告诉它有关系统调用返回错误的信息,然后是有关信号的信息。yes但是,从的角度来看,信号首先发生。(从技术上讲,信号是在内核将控制权返回给用户空间之后但在执行更多机器指令之前传递的,因此writeC库中的“包装器”函数没有机会设置errno并返回到应用程序。)
1可悲的是,strace它特定于Linux。大多数现代Unix都有一些执行类似操作的命令,但是它通常具有不同的名称,它可能无法彻底解码syscall参数,有时它仅适用于root用户。
               
              
yes | tee >(true) >/dev/null顺便说一句,它将继续如您所愿,tee直到所有作者都死了,所以true退出不会完全破坏它。