如果我不使用 stdout=subprocess,有什么区别。子进程中的管道。Popen()?



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

stdout=None(default)

我还看到人们使用stdout=subprocess。管。

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

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

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

有时,A2 命令在命令 A 完成之前执行。

stdout=None的意思是,进程的stdout句柄直接从父级继承而来,更简单的话说,它基本上意味着它被打印到控制台(同样适用于stderr)。

然后你有选项 stderr=STDOUT ,这会stderr重定向到stdout,这意味着stdoutstderr的输出被转发到同一个文件句柄。

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

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

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

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

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