He estado leyendo la documentación de Python sobre el módulo de subproceso (ver aquí ) y habla de unsubprocess.check_output()
comando que parece ser exactamente lo que necesito.
Sin embargo, cuando intento usarlo, aparece un error que indica que no existe y cuando lo ejecuto dir(subprocess)
no aparece en la lista.
Estoy ejecutando Python 2.6.5, y el código que he usado es el siguiente:
import subprocess
subprocess.check_output(["ls", "-l", "/dev/null"])
¿Alguien tiene alguna idea de por qué está sucediendo esto?
CalledProcessError
cuando el proceso devuelve un código de retorno distinto de cero.lambda
como esta:check_output = lambda args: Popen(args, stdout = PIPE).communicate()[0]
. Solo porque estoy en un intérprete interactivo y es una especie de PITA escribir defs de funciones de varias líneas en esos. Uséfrom subprocess import Popen, PIPE
anteriormente en la sesión.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 esquivar el golpe (también conocido como parche de mono) en cualquier lugar donde se importe el subproceso ...
Simplemente levante el código de 2.7 e insértelo así ...
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
Es posible que se requiera inquietud leve.
Tenga en cuenta que la responsabilidad recae en usted para mantener pequeños puertos sucios como este. Si se descubren errores y se corrigen en la última versión de Python, entonces a) debe notarlo yb) actualizar su versión si desea mantenerse seguro. Además, anular y definir las funciones internas por ti mismo es la peor pesadilla del próximo chico, especialmente cuando el próximo chico eres USTED varios años después y te has olvidado de los trucos divertidos que hiciste la última vez. En resumen: rara vez es una buena idea.
fuente
check_output
para Python 2.7 está actualmente aquí: github.com/python/cpython/blob/2.7/Lib/subprocess.py#L194Gracias a la sugerencia del parche de mono (y mis intentos fallaron, pero estábamos consumiendo la salida de CalledProcessError, así que necesitábamos parchear eso)
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
fuente