Python subprocess的stderr/stdout字段为None时如何处理

4 投票
1 回答
3584 浏览
提问于 2025-04-18 17:42

当我用一个文件流来创建一个Python的子进程,并把它作为 stderr(或者 stdout)的时候,相关的字段却是 None

s = subprocess.Popen(['ls','qwer'],
                     stdout=subprocess.PIPE,
                     stdin=subprocess.PIPE,
                     stderr=open("zzzzz",'wb'))
s.stderr is None
==> True

(我原本以为 s.stderr 应该是那个文件流。)

  • 这是有说明的吗?是故意这样设计的吗?
  • 这样做的原因是什么?

1 个回答

7

是的,这种设计是故意的。当你在创建 Popen 对象时提供 stdoutstdinstderr 这些参数时,其实是在告诉程序如何处理子进程中的输入和输出:

stdinstdoutstderr 分别代表执行程序的标准输入、标准输出和标准错误输出。

不过,在 Popen 对象上,stdoutstdinstderr 这些属性只有在你使用 PIPE 时才会有值:

Popen.stdin

如果 stdin 参数是 PIPE,那么这个属性就是一个文件对象,用来给子进程提供输入。否则,它的值是 None。

Popen.stdout

如果 stdout 参数是 PIPE,那么这个属性就是一个文件对象,用来接收子进程的输出。否则,它的值是 None。

Popen.stderr

如果 stderr 参数是 PIPE,那么这个属性就是一个文件对象,用来接收子进程的错误输出。否则,它的值是 None。

至于为什么当你传入其他类型的句柄时,Popen.std* 会是 None,我不太确定。可能是因为这样被认为是多余的,因为你本来就需要传一个打开的句柄给构造函数?

撰写回答