我最近在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命令。
答案 0 :(得分:13)
stdout=None
意味着,来自进程的stdout
- 句柄直接从父进程继承,更简单的说法就是它被打印到控制台(同样适用于stderr
)。
然后您选择stderr=STDOUT
,这会将stderr
重定向到stdout
,这意味着stdout
和stderr
的输出会被转发到同一地点文件句柄。
如果设置stdout=PIPE
,Python会将数据从流程重定向到新的文件句柄,可以通过p.stdout
(p
找到Popen
个对象来访问)。您可以使用它来捕获流程的输出,或者stdin
将数据(不断地)发送到stdin
的情况。
但大多数情况下你想使用p.communicate
,它允许你将数据发送到流程一次(如果需要),如果流程完成,则返回完整的stderr
和stdout
! / 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
对象通过文件/迭代器读取接口