Python subprocess.Popen PIPE和SIGPIPE
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python subprocess.Popen PIPE和SIGPIPE相关的知识,希望对你有一定的参考价值。
当我浏览帖子时,我在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
。 - 当
proc1
退出时,proc2
将退出,proc1
试图将数据写入proc2
的stdin PIPE
。因为 当proc2
退出时,stdin PIPE
的proc2
关闭SIGPIPE
发生在proc1
因为proc1
试图写封闭的proc2
的stdin PIPE
。
从我的理解,SIGPIPE
将发生,proc1
将退出,无论关闭proc1
的stdout
。
我错过了什么?
编辑
从@ unutbu的评论中读到post之后......
我认为复制的文件描述符(proc1.stdout
)是编写者PIPE,而不是读者PIPE。因此,有两个作者PIPE和一个读者PIPE相互连接。
因此,当SIGPIPE
退出时将生成proc2
,因为proc2
只有一个有读者PIPE的过程(当proc2
退出时将关闭)。
然而,上面的post似乎说通过复制proc1.stdout
有两个读者PIPE所以即使在SIGPIPE
退出后也不会生成proc2
,因为还有另一个读者PIPE打开。以下是post的一部分。
因此,通过立即关闭p1.stdout,您可以确保从dmesg stdout读取的唯一剩余文件句柄是grep进程,如果该进程要退出,则dmesg会收到SIGPIPE。
我不是说post是错的,但我只是想解决我的理解。先感谢您。
proc1 = subprocess.Popen(['ps', 'cax'], stdout=subprocess.PIPE)
在父进程和proc1
之间创建一个管道:
| | | |
| parent |-<-----<-| proc1 |
| | ^ | |
|
p1.stdout
p1.stdout
是父母从proc1
获得(stdout)输出的内容。
proc2 = subprocess.Popen(['grep', 'python'], stdin=proc1.stdout,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
连接从proc1到proc2的管道副本:
| | | | | |
| parent |-<-----<-| proc1 |->----->-| proc2 |
| | | | | |
通过调用p1.stdout.close()
,我们关闭管道的父进程:
| | | | | |
| parent | <-| proc1 |->----->-| proc2 |
| | | | | |
现在当proc2
终止时,管道的一侧也关闭了:
| | | | | |
| parent | <-| proc1 |-> | proc2 |
| | | | | |
下一次proc1
尝试写入管道时,会生成一个SIGPIPE信号,允许proc1
终止,因为它知道没有人正在监听其管道的另一端。
以上是关于Python subprocess.Popen PIPE和SIGPIPE的主要内容,如果未能解决你的问题,请参考以下文章
Python3 FileNotFoundError 与任何文件,使用 subprocess.popen()