【发布时间】:2013-09-24 03:22:27
【问题描述】:
我有这个:
$ ls -lh file
-rw-r--r-- 1 ankur root 181M Sep 23 20:09 file
$ head -6 file
z
abc
abc
abc
abc
abc
$ cat file | grep -m 1 z
z
问题:
为什么最后一行的cat 命令行不会因 SIGPIPE 而过早死亡?我认为这应该发生,因为与 cat file 相比,grep 立即终止了 183MB 的文件。随着阅读过程的结束cat 将尝试写入损坏的管道,并且应该与 SIGPIPE 一起死。
更新:
我最终写了这个:readstdin.c
# include <unistd.h>
# include <stdio.h>
int main() {
ssize_t n ;
char a[5];
n = read(0, a, 3);
printf("read %zd bytes\n", n);
return(0);
}
我是这样使用的:
$ cat file | ./readstdin
$ yes | ./readstdin
但cat 或yes 仍然不会过早死亡。我希望它会这样,因为通过读取过程在写入过程完成写入之前终止。
【问题讨论】:
-
yes正在死去,否则它将永远存在...... -
正如 Basile Starynkevitch 所说,
cat和yes进程收到SIGPIPE信号并被杀死。管道的退出状态是最终命令的退出状态(即grep),因此如果较早的命令失败,您将不会在退出状态中看到它。是什么让您认为他们不会过早死亡? -
@AdamRosenfield 让你认为他们不会过早死亡的事实是,我没有看到屏幕上打印出来自
cat或yes的错误消息,他们只是默默地退出。但这可能是它们被实施以处理 SIGPIPE 的方式。 -
@abc:
SIGPIPE信号的默认行为是静默终止进程。尝试编译并运行一个只执行main() { raise(SIGPIPE); }的程序——它不会产生任何输出。