12

我最近在 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 命令。

4

2 回答 2

24

stdout=None意味着,stdout进程中的 -handle 直接从父进程继承,简单来说,它基本上意味着,它被打印到控制台(同样适用于stderr)。

然后您可以选择stderr=STDOUT,这将重定向stderrstdout,这意味着 和 的输出stdoutstderr转发到同一个文件句柄。

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

一个更有趣的事实是,您可以将任何传递file-objectstdin/stderr/stdout,例如,也可以传递一个用打开的文件open(对象必须提供一种fileno()方法)。

对你的wait问题。这不应该是这样!作为解决方法,您可以使用它p.poll()来检查进程是否退出!调用的返回值是wait多少?

此外,您应该避免shell=True将用户输入作为第一个参数传递,这可能会被恶意用户用来利用您的程序!它还启动了一个 shell 进程,这意味着额外的开销。当然,有 1% 的情况是您实际需要shell=True的,我无法用您的简约示例来判断这一点。

于 2013-11-13T18:13:43.443 回答
5
  • stdout=None意味着子进程打印到脚本打印的任何位置
  • stdout=PIPE意味着子进程的标准输出被重定向到您应该读取的管道,例如,使用process.communicate()一次读取全部或使用process.stdout对象通过文件/迭代器接口读取
于 2013-11-13T18:09:03.437 回答