2009-04-01 14 views
33

¿Cómo puedo llamar a un programa externo con un script python y recuperar el código de salida y retorno?¿Cómo llamar a un programa externo en python y recuperar el código de salida y retorno?

+2

Existen algunas preguntas y respuestas sobre SO que te ayudarán: http://stackoverflow.com/questions/89228/how-to-call-external-command-in-python –

+0

Posible duplicado de [Llamar a un comando externo en Python] (http://stackoverflow.com/questions/89228/calling-an-external-command-in-python) –

Respuesta

45

Mira el módulo de subprocess: un ejemplo sencillo sigue ...

from subprocess import Popen, PIPE 

process = Popen(["ls", "-la", "."], stdout=PIPE) 
(output, err) = process.communicate() 
exit_code = process.wait() 
+10

He editado la respuesta anterior para reflejar la sugerencia de Ambroz en caso de que alguien lo haga no lee los comentarios y usa el código previamente incorrecto. –

+0

si esto no funciona por alguna razón, es posible que desee agregar shell = True a los parámetros (¿en Windows?) – ntg

+0

Parece que [la solución anterior] (https://stackoverflow.com/a/707001/1321680) puede reemplazarse por una simple llamada ['subprocess.run()'] (https://docs.python.org/dev/library/subprocess.html#subprocess.run) (se requiere Python> = 3.5). –

13

Siguiendo el comentario anterior de Ambroz Bizjak, aquí es una solución que funcionó para mí:

import shlex 
from subprocess import Popen, PIPE 

cmd = "..." 
process = Popen(shlex.split(cmd), stdout=PIPE) 
process.communicate() 
exit_code = process.wait() 
+3

Esta es de lejos la mejor respuesta. – dotancohen

+3

Tengo una publicación similar [aquí] (https://stackoverflow.com/questions/1996518/retrieving-the-output-of-subprocess-call/21000308#21000308) que muestra cómo obtener tres cosas de un proceso: exitcode , stdout, stderr. – Jabba

2

Después de algunas investigaciones, tengo el siguiente código que funciona muy bien para mí. Básicamente imprime stdout y stderr en tiempo real. Espero que ayude a alguien más que lo necesite.

stdout_result = 1 
stderr_result = 1 


def stdout_thread(pipe): 
    global stdout_result 
    while True: 
     out = pipe.stdout.read(1) 
     stdout_result = pipe.poll() 
     if out == '' and stdout_result is not None: 
      break 

     if out != '': 
      sys.stdout.write(out) 
      sys.stdout.flush() 


def stderr_thread(pipe): 
    global stderr_result 
    while True: 
     err = pipe.stderr.read(1) 
     stderr_result = pipe.poll() 
     if err == '' and stderr_result is not None: 
      break 

     if err != '': 
      sys.stdout.write(err) 
      sys.stdout.flush() 


def exec_command(command, cwd=None): 
    if cwd is not None: 
     print '[' + ' '.join(command) + '] in ' + cwd 
    else: 
     print '[' + ' '.join(command) + ']' 

    p = subprocess.Popen(
     command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd 
    ) 

    out_thread = threading.Thread(name='stdout_thread', target=stdout_thread, args=(p,)) 
    err_thread = threading.Thread(name='stderr_thread', target=stderr_thread, args=(p,)) 

    err_thread.start() 
    out_thread.start() 

    out_thread.join() 
    err_thread.join() 

    return stdout_result + stderr_result 
3

he desarrollado una pequeña biblioteca (py-execute) que permite ejecutar programas externos, recuperar la salida y el retcode y, al mismo tiempo, obtener una salida en la consola en tiempo real:

>>> from py_execute.process_executor import execute 
>>> ret = execute('echo "Hello"') 
Hello 
>>> ret 
(0, 'Hello\n') 

puede evitar que se imprima a la consola pasar un simulacro user_io:

>>> from mock import Mock 
>>> execute('echo "Hello"', ui=Mock()) 
(0, 'Hello\n') 

lo escribí porque la llanura Popen (En Python 2.7) que estaba teniendo problemas para ejecutar comunicaciones ys con una salida larga

Cuestiones relacionadas