我对管道的新认识

sh/bash/dash/ksh/zsh等Shell脚本
回复
blue-fish
帖子: 8
注册时间: 2009-09-27 11:26

我对管道的新认识

#1

帖子 blue-fish » 2015-05-18 18:43

之前一直以为诸如 p1 | p2 的运行方式是: 首先运行 p1, 等 p1 运行完毕后,再将其输出传给 p2。

但今天在 ubuntu 14 上试验了下,发现以前认识错了。

真实的情况是,p1 和 p2 是同时运行的,且它们是父子进程的关系(具体哪个是父进程,没研究,运行过程中我 kill 了 p2, p1也随之退出了),

p1 的输出会随时传输给p2,直到结束。

这一特性很有用。
头像
astolia
论坛版主
帖子: 6444
注册时间: 2008-09-18 13:11

Re: 我对管道的新认识

#2

帖子 astolia » 2015-05-19 11:21

你的新认识也有错误。p1和p2不是父子进程。你运行后用pstree看,可以直观的看到两者是并列层级的
之所以结束了p2,p1也退出了,是因为往一个没有读入端的管道写东西会触发一个SIGPIPE信号,而这个信号的默认处理是中止进程
建议去看看manpage中对管道的说明

代码: 全选

man 7 pipe
If all file descriptors referring to the write end of a pipe have been
closed, then an attempt to read(2) from the pipe will see end-of-file
(read(2) will return 0). If all file descriptors referring to the read
end of a pipe have been closed, then a write(2) will cause a SIGPIPE
signal to be generated for the calling process.
If the calling process
is ignoring this signal, then write(2) fails with the error EPIPE. An
application that uses pipe(2) and fork(2) should use suitable close(2)
calls to close unnecessary duplicate file descriptors; this ensures
that end-of-file and SIGPIPE/EPIPE are delivered when appropriate.
上面这段文字也说明了为什么结束p1,p2是正常退出
回复