Pregunta subprocess.check_output () no parece existir (Python 2.6.5)


He estado leyendo la documentación de Python sobre el módulo de subproceso (ver aquí) y habla de un subprocess.check_output() comando que parece ser exactamente lo que necesito.

Sin embargo, cuando intento y lo uso me sale un error de que no existe, y cuando corro dir(subprocess) no está en la lista.

Estoy ejecutando Python 2.6.5, y el código que he usado está a continuación:

import subprocess
subprocess.check_output(["ls", "-l", "/dev/null"])

¿Alguien tiene alguna idea de por qué está pasando esto?


73
2018-01-27 10:05


origen


Respuestas:


Fue introducido en 2.7 Ver el documentos.

Utilizar subproceso.Popen si quieres la salida:

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

114
2018-01-27 10:07



SI se usa mucho en el código que desea ejecutar, pero ese código no tiene que mantenerse a largo plazo (o necesita una solución rápida independientemente de los posibles dolores de cabeza de mantenimiento en el futuro), entonces podría agachar el golpe (también conocido como parche de mono) en donde se importa el subproceso ...

Simplemente levante el código de 2.7 e insértelo de esta manera ...

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

Inquietud menor puede ser requerida.

Tenga en cuenta que la responsabilidad recae en usted para mantener los pequeños backports sucios como este. Si se descubren y corrigen errores en la última versión de python, entonces a) tiene que darse cuenta de eso yb) actualizar su versión si desea permanecer seguro. Además, anular y definir las funciones internas tú mismo es la peor pesadilla del siguiente tipo, especialmente cuando el próximo tipo eres TU, varios años después, ¡y te olvidaste de todos los hackers que hiciste la última vez! En resumen: rara vez es una buena idea.


54
2017-10-31 14:53



Gracias a la sugerencia del parche de mono (y mis intentos fallaron, pero estábamos consumiendo la salida de CalledProcessError, así que necesitamos parche de mono que)

encontré un parche 2.6 que funciona aquí: 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

4
2017-12-03 00:02