如果我输入,怎么会发生:
cat /dev/urandom
Run Code Online (Sandbox Code Playgroud)
那么输出数据将花费很长时间,但是:
cat /dev/urandom | head -c 10
Run Code Online (Sandbox Code Playgroud)
输出在 10 个随机字节后结束,是否head指示以某种方式cat完成其输出?
该cat会得到一个SIGPIPE当它试图写入,没有读者的管道信号(时head终止,它会自动关闭其标准输入,这也是唯一打开的句柄到管道的读出端)。
如果您以某种方式获得管道读取端的另一个句柄,则 cat 将不会完成,而是在填满管道缓冲区后阻塞:
(仅限 Linux 的示例):
cat /dev/urandom 3</dev/stdout | head -c 10 > /tmp/junk
<staying there until you ^C>
Run Code Online (Sandbox Code Playgroud)
另外,如果你cat要忽略的SIGPIPE信号,这将已经生成的写SIGPIPE信号将直接失败,设置errno于EPIPE= Broken pipe ^ 1:
{ trap '' PIPE; cat /dev/urandom; } | head -c 10 >/tmp/junk
cat: write error: Broken pipe
Run Code Online (Sandbox Code Playgroud)
这个head过程与这一切无关。它根本不发出、指示或关心cat; 它只是读取它需要的任何内容然后退出,让操作系统来处理所有其余的事情。
^1后一种行为(非常烦人)是 Python 脚本的默认行为:
python -c 'while 1: print("hello")' | head -n2
hello
hello
Traceback (most recent call last):
File "<string>", line 1, in <module>
IOError: [Errno 32] Broken pipe
Run Code Online (Sandbox Code Playgroud)