head 如何在以下命令中停止 cat : cat /dev/urandom | 头-c 10

mik*_*ike 0 shell

如果我输入,怎么会发生:

cat /dev/urandom
Run Code Online (Sandbox Code Playgroud)

那么输出数据将花费很长时间,但是:

cat /dev/urandom | head -c 10
Run Code Online (Sandbox Code Playgroud)

输出在 10 个随机字节后结束,是否head指示以某种方式cat完成其输出?

use*_*777 5

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信号将直接失败,设置errnoEPIPE= 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)