【问题标题】:What is the difference if I don't use stdout=subprocess.PIPE in subprocess.Popen()?如果我在 subprocess.Popen() 中不使用 stdout=subprocess.PIPE 有什么区别?
【发布时间】:2013-11-26 11:36:13
【问题描述】:

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

stdout=None(default)

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

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

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

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

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

【问题讨论】:

  • 在其他示例中,人们是否将其中一个的输出用作下一个流程的输入?
  • 您如何确定子流程并未真正完成? process.wait() 在子进程退出之前不会返回,但如果子进程有自己的子进程,那么它可能会在其所有子进程完成之前退出

标签: python subprocess stdout


【解决方案1】:

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

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

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

还有一个有趣的事实,您可以将任何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,我不能用你的简约例子来判断。

【讨论】:

  • 您不能只传递任何文件对象。它应该是具有有效.fileno() 的文件对象,例如,StringIO() 将不起作用。
  • 是的,我知道,但我不想写file-like,因为StringIOfile-like,有什么想法可以正确表达吗?
  • “任何带有.fileno()方法的对象返回一个现有的文件描述符”例如,socket works on my machine
  • 遇到了这个问题,因为我也在寻找答案。但是我并不完全理解答案 - 那么是否可以使用stdout=subprocess.PIPE
  • @yan:使用stdout=PIPE 当且仅当您打算从进程中读取'stdout。清楚了吗?
【解决方案2】:
  • stdout=None 表示子进程打印到脚本打印的任何位置
  • stdout=PIPE 表示子进程的 stdout 被重定向到您应该读取的管道,例如,使用 process.communicate() 一次读取全部或使用 process.stdout 对象通过文件/迭代器接口读取

【讨论】:

    猜你喜欢
    • 2012-03-25
    • 1970-01-01
    • 1970-01-01
    • 2013-05-22
    • 2018-09-12
    • 2017-01-04
    • 1970-01-01
    • 2020-04-25
    • 1970-01-01
    相关资源
    最近更新 更多