subprocess.check_output()似乎不存在(Python 2.6.5)

rob*_*ntw 77 python

我一直在阅读有关子进程模块的Python文档(参见此处),它讨论的subprocess.check_output()命令似乎正是我需要的.

但是,当我尝试使用它时,我得到一个它不存在的错误,当我运行dir(subprocess)它时没有列出.

我正在运行Python 2.6.5,我使用的代码如下:

import subprocess
subprocess.check_output(["ls", "-l", "/dev/null"])
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么会这样?

use*_*312 120

它是在2.7中引入的.参见文档.

如果要输出,请使用subprocess.Popen:

>>> import subprocess
>>> output = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE).communicate()[0]
Run Code Online (Sandbox Code Playgroud)

  • 与check_output不同,当进程返回非零返回码时,这不会引发`CalledProcessError`. (14认同)

tec*_*oke 55

如果它在您想要运行的代码中被大量使用但是该代码不必长期维护(或者您需要快速修复,而不管将来可能出现的维护问题)那么您可以使用它(也就是猴子补丁)它在任何子进程导入的地方......

只需从2.7中提取代码并插入即可......

import subprocess

if "check_output" not in dir( subprocess ): # duck punch it in!
    def f(*popenargs, **kwargs):
        if 'stdout' in kwargs:
            raise ValueError('stdout argument not allowed, it will be overridden.')
        process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
        output, unused_err = process.communicate()
        retcode = process.poll()
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
            raise subprocess.CalledProcessError(retcode, cmd)
        return output
    subprocess.check_output = f
Run Code Online (Sandbox Code Playgroud)

可能需要轻微的烦躁不安.

请记住,虽然你有责任维持像这样的肮脏的小后端.如果在最新的python中发现并纠正了错误,那么你a)必须注意到这一点,并且b)如果你想保持安全,请更新你的版本.此外,自己压倒和定义内部功能是下一个人最糟糕的噩梦,特别是当下一个人是你几年后,你已经忘记了上次你做的那些肮脏的黑客!总结:这很少是一个好主意.

  • 我同意这种方法.我可能包括源的位置.你可以在http://hg.python.org/cpython/file/d37f963394aa/Lib/subprocess.py#l544找到它. (2认同)

kee*_*een 6

多亏了猴子补丁的建议(而且我的尝试失败了-但是我们正在使用CalledProcessError输出,因此需要猴子补丁)

在此处找到了有效的2.6补丁:http : //pydoc.net/Python/pep8radius/0.9.0/pep8radius.shell/

"""Note: We also monkey-patch subprocess for python 2.6 to
give feature parity with later versions.
"""
try:
    from subprocess import STDOUT, check_output, CalledProcessError
except ImportError:  # pragma: no cover
    # python 2.6 doesn't include check_output
    # monkey patch it in!
    import subprocess
    STDOUT = subprocess.STDOUT

    def check_output(*popenargs, **kwargs):
        if 'stdout' in kwargs:  # pragma: no cover
            raise ValueError('stdout argument not allowed, '
                             'it will be overridden.')
        process = subprocess.Popen(stdout=subprocess.PIPE,
                                   *popenargs, **kwargs)
        output, _ = process.communicate()
        retcode = process.poll()
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
            raise subprocess.CalledProcessError(retcode, cmd,
                                                output=output)
        return output
    subprocess.check_output = check_output

    # overwrite CalledProcessError due to `output`
    # keyword not being available (in 2.6)
    class CalledProcessError(Exception):

        def __init__(self, returncode, cmd, output=None):
            self.returncode = returncode
            self.cmd = cmd
            self.output = output

        def __str__(self):
            return "Command '%s' returned non-zero exit status %d" % (
                self.cmd, self.returncode)
    subprocess.CalledProcessError = CalledProcessError
Run Code Online (Sandbox Code Playgroud)