6

为什么不yes | head挂?

我认为系统会收集所有结果yes,然后将其通过管道传输到head,并且由于yes是无限循环,因此系统挂起。但是,它实际上可以停止并显示 10 行y.

收集数据完成后系统如何停止yeshead

4

2 回答 2

5

当您说yes | head外壳将安排事情时,输出yes进入管道,输入head来自同一管道。当head读取 10 行时,它关闭它的 STDIN_FILENO,从而关闭它的管道末端。当yes试图写入一个封闭的管道时,它会得到一个SIGPIPE默认操作是杀死它。

一个简单的测试方法是strace

$ strace yes | head
y
[...]
y
write(1, "y\ny\ny\ny\ny\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=4069, si_uid=1000} ---
+++ killed by SIGPIPE +++
于 2014-01-25T12:42:39.487 回答
4

系统从 yes 收集所有结果,然后将其通过管道传送到 head

那将是非常低效的。当您使用管道时,操作系统会为管道通信创建一个缓冲区。

send | receive

只要缓冲区中有足够的空间,发送进程就会写入其中,如果缓冲区中有足够的数据,接收者就会处理它。如果没有等待进程被阻塞。

一旦head完成,操作系统就会注意到它已终止,它将触发一个信号 ( SIGPIPE),该信号将终止发送进程(除非进程处理它)。

于 2014-01-25T12:41:30.073 回答