2009-04-01 7 views
33

Wie kann ich ein externes Programm mit einem Python-Skript aufrufen und den Ausgabe- und Rückgabecode abrufen?Wie ein externes Programm in Python aufrufen und den Ausgabe- und Rückgabecode abrufen?

+2

Es gibt einige bestehende Fragen und Antworten zu SO, die Ihnen helfen werden: http://stackoverflow.com/questions/89228/how-to-call-external-command-in-python –

+0

Mögliche doppelte von [Aufruf eines externen Befehls in Python] (http://stackoverflow.com/questions/89228/calling-an-external-command-in-python) –

Antwort

45

Blick auf das subprocess-Modul: ein einfaches Beispiel ...

from subprocess import Popen, PIPE 

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

Ich habe die obige Antwort bearbeitet, um den Vorschlag von Ambroz zu reflektieren, falls jemand das tut lese die Kommentare nicht und verwende den zuvor falschen Code. –

+0

Wenn dies aus irgendeinem Grund nicht funktioniert, möchten Sie möglicherweise Shell = True zu den Parametern hinzufügen (wenn in Windows?) – ntg

+0

Es scheint, dass [die obige Lösung] (https://stackoverflow.com/a/707001/1321680) kann durch einfachen Aufruf ['subprocess.run()'] (https://docs.python.org/dev/library/subprocess.html#subprocess.run) ersetzt werden (Python> = 3.5 ist erforderlich). –

13

Nach Ambroz Bizjak der vorherigen Kommentar, hier ist eine Lösung, die für mich gearbeitet:

import shlex 
from subprocess import Popen, PIPE 

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

Dies ist bei weitem die beste Antwort. – dotancohen

+3

Ich habe einen ähnlichen Beitrag [hier] (https://stackoverflow.com/questions/1996518/retrieving-the-output-of-subprocess-call/21000308#21000308), die zeigt, wie man drei Dinge aus einem Prozess zu bekommen: Exitcode , stdout, stderr. – Jabba

2

Nach einigen Recherchen habe ich den folgenden Code, die für mich sehr gut funktioniert. Es druckt grundsätzlich sowohl stdout als auch stderr in Echtzeit. Ich hoffe, es hilft jemandem, der es braucht.

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

Ich habe eine kleine Bibliothek (py-execute) entwickelt, die Sie externe Programme ausführen können, rufen Sie die Ausgabe und die retcode und zugleich Ausgabe in der Konsole in Echtzeit erhalten:

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

Sie Druck vermeiden kann ein Mock user_io zu trösten vorbei:

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

schrieb ich es, weil mit einfachen Popen (In Python 2.7) ich Probleme Ausführung comm aufweist, wurde ands mit einer langen Ausgabe

Verwandte Themen