subprocess.check_output example python
Recuperando la salida de subprocess.call() (7)
Esta pregunta ya tiene una respuesta aquí:
¿Cómo puedo obtener la salida de un proceso ejecutado utilizando subprocess.call()
?
Pasar un objeto StringIO.StringIO
a la StringIO.StringIO
da este error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/subprocess.py", line 444, in call
return Popen(*popenargs, **kwargs).wait()
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/subprocess.py", line 588, in __init__
errread, errwrite) = self._get_handles(stdin, stdout, stderr)
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/subprocess.py", line 945, in _get_handles
c2pwrite = stdout.fileno()
AttributeError: StringIO instance has no attribute ''fileno''
>>>
En shell Ipython
:
In [8]: import subprocess
In [9]: s=subprocess.check_output(["echo", "Hello World!"])
In [10]: s
Out[10]: ''Hello World!/n''
Basado en la respuesta de sargue. Crédito a sargue.
La salida de subprocess.call()
solo se debe redirigir a archivos.
Deberías usar subprocess.Popen()
lugar. Luego puede pasar subprocess.PIPE
para los parámetros stderr, stdout y / o stdin y leer desde las tuberías utilizando el método communicate()
:
from subprocess import Popen, PIPE
p = Popen([''program'', ''arg1''], stdin=PIPE, stdout=PIPE, stderr=PIPE)
output, err = p.communicate(b"input data that is passed to subprocess'' stdin")
rc = p.returncode
El razonamiento es que el objeto tipo archivo utilizado por subprocess.call()
debe tener un descriptor de archivo real, y así implementar el método fileno()
. El solo uso de cualquier objeto similar a un archivo no hará el truco.
Vea here para más información.
Lo siguiente captura stdout y stderr del proceso en una sola variable. Es compatible con Python 2 y 3:
from subprocess import check_output
command = ["ls", "-l"]
try:
output = check_output(command, stderr=STDOUT).decode()
success = True
except CalledProcessError as e:
output = e.output.decode()
success = False
Si su comando es una cadena en lugar de una matriz, prefija esto con:
import shlex
command = shlex.split(command)
Para Python 3.5+, se recomienda que use la subprocess.run . Esto devuelve un objeto CompletedProcess
, desde el cual puede obtener fácilmente el resultado y el código de retorno.
from subprocess import PIPE, run
command = [''echo'', ''hello'']
result = run(command, stdout=PIPE, stderr=PIPE, universal_newlines=True)
print(result.returncode, result.stdout, result.stderr)
Recientemente descubrí cómo hacer esto, y aquí hay un ejemplo de código de un proyecto actual mío:
#Getting the random picture.
#First find all pictures:
import shlex, subprocess
cmd = ''find ../Pictures/ -regex ".*/(JPG/|NEF/|jpg/)" ''
#cmd = raw_input("shell:")
args = shlex.split(cmd)
output,error = subprocess.Popen(args,stdout = subprocess.PIPE, stderr= subprocess.PIPE).communicate()
#Another way to get output
#output = subprocess.Popen(args,stdout = subprocess.PIPE).stdout
ber = raw_input("search complete, display results?")
print output
#... and on to the selection process ...
Ahora tiene la salida del comando almacenado en la variable "salida". "stdout = subprocess.PIPE" le dice a la clase que cree un objeto de archivo llamado ''stdout'' desde Popen. El método de comunicación (), por lo que puedo decir, simplemente actúa como una forma conveniente de devolver una tupla de la salida y los errores del proceso que ha ejecutado. Además, el proceso se ejecuta al crear una instancia de Popen.
Si tiene la versión de Python> = 2.7, puede usar subprocess.check_output que básicamente hace exactamente lo que quiere (devuelve una salida estándar como cadena).
Ejemplo simple (versión de linux, ver nota):
import subprocess
print subprocess.check_output(["ping", "-c", "1", "8.8.8.8"])
Tenga en cuenta que el comando ping está usando la notación de linux ( -c
para contar). Si intenta esto en Windows, recuerde cambiarlo a -n
para obtener el mismo resultado.
Como se comenta a continuación, puede encontrar una explicación más detallada en esta otra respuesta .
Tengo la siguiente solución. Captura el código de salida, el stdout y el stderr también del comando externo ejecutado:
import shlex
from subprocess import Popen, PIPE
def get_exitcode_stdout_stderr(cmd):
"""
Execute the external command and get its exitcode, stdout and stderr.
"""
args = shlex.split(cmd)
proc = Popen(args, stdout=PIPE, stderr=PIPE)
out, err = proc.communicate()
exitcode = proc.returncode
#
return exitcode, out, err
cmd = "..." # arbitrary external command, e.g. "python mytest.py"
exitcode, out, err = get_exitcode_stdout_stderr(cmd)
También tengo una entrada de blog here .
Editar: la solución se actualizó a una más nueva que no necesita escribir en temp. archivos.