example check_output python pipe subprocess stringio

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.