如果我不在subprocess.Popen()中使用stdout = subprocess.PIPE,有什么区别?

时间:2013-11-13 18:00:44

标签: python subprocess stdout

我最近在Python中注意到subprocess.Popen()有一个参数:

stdout=None(default)

我也看到人们使用stdout = subprocess.PIPE。

有什么区别?我应该使用哪一个?

另一个问题是,为什么wait()函数不能等到有时完成进程?我用过:

a = sp.Popen(....,shell=True)
a.wait()
a2 = sp.Popen(...,shell=True)
a2.wait()

有时在命令a完成之前执行a2命令。

2 个答案:

答案 0 :(得分:13)

stdout=None意味着,来自进程的stdout - 句柄直接从父进程继承,更简单的说法就是它被打印到控制台(同样适用于stderr )。

然后您选择stderr=STDOUT,这会将stderr重定向到stdout,这意味着stdoutstderr的输出会被转发到同一地点文件句柄。

如果设置stdout=PIPE,Python会将数据从流程重定向到新的文件句柄,可以通过p.stdoutp找到Popen个对象来访问)。您可以使用它来捕获流程的输出,或者stdin将数据(不断地)发送到stdin的情况。 但大多数情况下你想使用p.communicate,它允许你将数据发送到流程一次(如果需要),如果流程完成,则返回完整的stderrstdout! / p>

另一个有趣的事实是,您可以将file-object传递给stdin/stderr/stdout,例如还有一个用open打开的文件(该对象必须提供fileno()方法)。

解决您的wait问题。情况应该不是这样!作为解决方法,您可以使用p.poll()来检查进程是否已退出! wait电话的返回值是什么?

Furthermore, you should avoid shell=True especially if you pass user-input as first argument,恶意用户可以使用它来利用您的程序!它还启动了一个shell进程,这意味着额外的开销。当然,有1%的情况下您确实需要shell=True,我无法用您的简约示例判断这一点。

答案 1 :(得分:4)

  • stdout=None表示子流程打印到脚本打印的任何位置
  • stdout=PIPE表示子进程'stdout被重定向到您应该读取的管道,例如,使用process.communicate()一次读取所有内容或使用process.stdout对象通过文件/迭代器读取接口