【发布时间】:2018-06-08 16:01:25
【问题描述】:
当我浏览帖子时,我在here 上遇到了以下示例,它说需要调用proc1.stdout.close() 才能正确退出proc1,生成SIGPIPE。
import subprocess
proc1 = subprocess.Popen(['ps', 'cax'], stdout=subprocess.PIPE)
proc2 = subprocess.Popen(['grep', 'python'], stdin=proc1.stdout,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
proc1.stdout.close() # Allow proc1 to receive a SIGPIPE if proc2 exits.
out, err = proc2.communicate()
print('out: {0}'.format(out))
print('err: {0}'.format(err))
但是,我不清楚这一点。请修正我的理解。
-
SIGPIPE发生在PIPE尝试写入已关闭的PIPE时。 - 作者
PIPE是proc1的stdout,读者PIPE是proc2的stdin。 -
当
proc2退出并且proc1尝试将数据写入proc2的stdin PIPE时,proc1将退出。 因为-
proc2的stdin PIPE在proc2退出时关闭 -
SIGPIPE发生在proc1,因为proc1尝试写入已关闭的proc2的stdin PIPE。
-
根据我的理解,SIGPIPE 会发生并且proc1 会退出,无论是否关闭proc1 的stdout。
我错过了什么?
编辑
从@unutbu 的评论中阅读post 后......
我认为复制的文件描述符(proc1.stdout)是写入器管道,而不是读取器管道。因此,有两个写入器 PIPE 和一个读取器 PIPE 相互连接。
因此,proc2 退出时会生成SIGPIPE,因为proc2 只是一个拥有读卡器PIPE 的进程(proc2 退出时将关闭)。
但是,上面的post 似乎通过复制proc1.stdout 表示有两个读取器PIPE,因此即使在proc2 退出后也不会生成SIGPIPE,因为还有另一个读取器PIPE 打开。以下是post的部分。
因此,通过立即关闭 p1.stdout,您可以确保唯一的 从 dmesg stdout 读取的剩余文件句柄是 grep 进程, 如果该进程退出,dmesg 会收到一个 SIGPIPE。
我并不是说post 是错误的,但我只是想修正我的理解。提前谢谢你。
【问题讨论】:
-
this post 回答你的问题了吗?
-
@unutbu,再次感谢您,我在阅读您回答中的帖子后编辑了我的问题。
标签: python linux subprocess pipe sigpipe