Comment puis-je appeler un programme externe avec un script python et récupérer le code de sortie et de retour?
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()
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()
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
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
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.