web-dev-qa-db-fra.com

Comment appeler un programme externe en python et récupérer la sortie et le code retour?

Comment puis-je appeler un programme externe avec un script python et récupérer le code de sortie et de retour?

48
cfischer

Regardez le module sous-processus : un exemple simple suit ...

from subprocess import Popen, PIPE

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

Suite au commentaire précédent d'Ambroz Bizjak, voici une solution qui a fonctionné pour moi:

import shlex
from subprocess import Popen, PIPE

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

J'ai développé une petite bibliothèque ( py-execute ) qui vous permet d'exécuter des programmes externes, de récupérer la sortie et le retcode et, en même temps, d'obtenir la sortie dans la console en temps réel:

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

Vous pouvez éviter d'imprimer sur la console en passant un faux user_io:

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

Je l'ai écrit car avec Popen ordinaire (In Python 2.7), j'avais du mal à exécuter des commandes avec une sortie longue

2
hithwen

Après quelques recherches, j'ai le code suivant qui fonctionne très bien pour moi. Il imprime essentiellement stdout et stderr en temps réel. J'espère que cela aide quelqu'un d'autre qui en a besoin.

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
2
Jake W

Découvrez le module de sous-processus ici: http://docs.python.org/library/subprocess.html#module-subprocess . Il devrait obtenir ce dont vous avez besoin.

2
David Ackerman