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