为什么python的subprocess.call是这样实现的? [英] Why is python's subprocess.call implemented like this?

查看:19
本文介绍了为什么python的subprocess.call是这样实现的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

subprocess 模块有方便的函数call,在2.6和3.1中都是这样实现的:

The subprocess module has the convenience function call, which is implemented like this in both 2.6 and 3.1:

def call(*popenargs, **kwargs):
    return Popen(*popenargs, **kwargs).wait()

该函数的文档带有红色警告,阅读:

The documentation for this function carries a red warning, reading:

警告:与 Popen.wait() 一样,使用 stdout=PIPE 和/或 stderr=PIPE 时会死锁 并且子进程向管道生成足够的输出,从而阻止等待 OS 管道缓冲区接受更多数据.

Warning: Like Popen.wait(), this will deadlock when using stdout=PIPE and/or stderr=PIPE and the child process generates enough output to a pipe such that it blocks waiting for the OS pipe buffer to accept more data.

Popen.wait() 文档说在这种情况下使用 Popen.communicate() 代替.好吧,那为什么不像下面那样实现 call ,这样愚蠢的警告可以被删除,并且像这样的愚蠢限制从标准库中删除?

The Popen.wait() documentation says to use Popen.communicate() instead in such circumstances. Well, then why isn't call just implemented like below instead, so the stupid warning can be removed, and silly limitations like this removed from the standard library?

def call(*args, **kwargs):
    input = kwargs.pop("input", None)
    p = Popen(*args, **kwargs)
    p.communicate(input)
    return p.returncode

我相信这是有原因的.我错过了什么?

I'm sure there's a reason. What am I missing?

推荐答案

我花了一些时间浏览 PEP-324,里面介绍了 subprocess 模块,试图弄清楚其中涉及的设计决策,但我认为答案其实很简单:

I spent some time looking through PEP-324, which introduced the subprocess module, trying to figure out the design decisions involved, but I think the answer is actually very simple:

没有理由stdout=PIPEstderr=PIPE 传递给 subprocess.call,所以它可以死锁的事实是无关紧要的.

There's no reason to pass stdout=PIPE or stderr=PIPE to subprocess.call, so the fact that it can deadlock is irrelevant.

stdout=PIPEstderr=PIPE 传递给 subprocess.Popen 的唯一原因是您可以使用 Popen 实例的 stdoutstderr 属性作为文件对象.由于 subprocess.call 从不让您看到 Popen 实例,PIPE 选项变得无关紧要.

The only reason to pass stdout=PIPE or stderr=PIPE to subprocess.Popen is so that you can use the Popen instance's stdout and stderr attributes as file objects. Since subprocess.call never lets you see the Popen instance, the PIPE options become irrelevant.

Popen.communicate 有潜在的开销(通过监视管道创建额外的线程以避免死锁),在这种情况下没有任何好处,因此没有理由使用它.

There is potential overhead to Popen.communicate (creating additional threads to avoid deadlock by monitoring the pipes), and there's no benefit in this case, so there's no reason to use it.

编辑:如果你想放弃你的输出,我想最好明确这样做:

Edit: If you want to discard your output, I guess it's better to do so explicitly:

# option 1
with open(os.devnull, 'w') as dev_null:
    subprocess.call(['command'], stdout=dev_null, stderr=dev_null)

# option 2
subprocess.call(['command >& /dev/null'], shell=True)

而不是指示子进程将所有输出捕获到您从未打算使用的 PIPE 文件中.

instead of instructing subprocess to capture all of the output to PIPE files that you never intend to use.

这篇关于为什么python的subprocess.call是这样实现的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆