在 subprocess 模块的 Python 2.7 文档中,我找到了以下片段:
p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]
来源 :https://docs.python.org/2/library/subprocess.html#replacing-shell-pipeline https://docs.python.org/2/library/subprocess.html#replacing-shell-pipeline
我不明白这一行:p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
这里 p1.stdout 被关闭。如果 p2 退出,它如何允许 p1 接收 SIGPIPE?
如果进程尝试写入没有活动进程正在查找的管道,则通常会发送 SIGPIPE 信号。在相当于代码片段的 shell 管道中:
`dmesg | grep hda`
If the grep
进程由于某种原因终止之前dmesg
完成写入输出,dmesg
将收到 SIGPIPE 并终止自身。这将是 UNIX/Linux 进程的预期行为(http://en.wikipedia.org/wiki/Unix_signal http://en.wikipedia.org/wiki/Unix_signal).
相比之下,在 Python 实现中使用subprocess
, if p2
之前退出p1
生成输出完成后,SIGPIPE 不会被发送,因为实际上仍然有一个进程在查看管道 - Python 脚本本身(创建的脚本)p1
and p2
)。更重要的是,脚本正在查看管道,但不消耗其内容 - 效果是管道无限期地保持打开状态,并且p1
陷入困境。
明确关闭p1.stdout
将 Python 脚本从管道中分离出来,并使得除了p2
正在看着管道 - 这样如果p2
之前结束p1
, p1
正确地让信号自行结束,而无需任何人为地保持管道打开。
这是一个替代措辞的解释:http://www.enricozini.org/2009/debian/python-pipes/ http://www.enricozini.org/2009/debian/python-pipes/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)