J'ai besoin d'exécuter une commande shell de manière asynchrone à partir d'un script Python. Je veux dire par là que je veux que mon script Python continue à s'exécuter pendant que la commande externe se déclenche et fait tout ce qu'elle doit faire.
J'ai lu cet article:
Je suis ensuite parti et j'ai fait des tests, et il semble que os.system()
je ferai le travail à condition que j'utilise &
à la fin de la commande afin de ne pas avoir à attendre son retour. Ce que je me demande, c'est si c'est la bonne façon d'accomplir une telle chose? J'ai essayé commands.call()
mais cela ne fonctionnera pas pour moi car il bloque sur la commande externe.
S'il vous plaît laissez-moi savoir si utiliser os.system()
pour cela est conseillé ou si je devrais essayer une autre voie.
la source
Si vous souhaitez exécuter de nombreux processus en parallèle, puis les gérer lorsqu'ils donnent des résultats, vous pouvez utiliser l'interrogation comme ci-dessous:
Le flux de contrôle y est un peu compliqué parce que j'essaie de le rendre petit - vous pouvez le refactoriser à votre goût. :-)
Cela présente l'avantage de répondre en premier aux demandes de finition anticipée. Si vous appelez
communicate
le premier processus en cours d'exécution et que celui-ci s'exécute le plus longtemps, les autres processus en cours d'exécution seront restés inactifs alors que vous auriez pu gérer leurs résultats.la source
os.waitpid
directement ce qui permet de vérifier si un processus enfant a changé son statut.['/usr/bin/my_cmd', '-i', path]
place de['/usr/bin/my_cmd', '-i %s' % path]
Ce que je me demande, c'est si ce [os.system ()] est la bonne façon d'accomplir une telle chose?
Non, ce
os.system()
n'est pas la bonne manière. C'est pourquoi tout le monde dit d'utilisersubprocess
.Pour plus d'informations, lisez http://docs.python.org/library/os.html#os.system
la source
J'ai eu un bon succès avec le module asyncproc , qui traite bien la sortie des processus. Par exemple:
la source
Utiliser pexpect avec des readlines non bloquantes est une autre façon de le faire. Pexpect résout les problèmes de blocage, vous permet d'exécuter facilement les processus en arrière-plan et offre des moyens faciles d'avoir des rappels lorsque votre processus crache des chaînes prédéfinies, et facilite généralement l'interaction avec le processus.
la source
Considérant "Je n'ai pas à attendre son retour", l'une des solutions les plus simples sera la suivante:
Mais ... D'après ce que j'ai lu, ce n'est pas "la bonne façon d'accomplir une telle chose" à cause des risques de sécurité créés par le
subprocess.CREATE_NEW_CONSOLE
drapeau.Les choses clés qui se produisent ici sont l'utilisation de
subprocess.CREATE_NEW_CONSOLE
pour créer une nouvelle console et.pid
(retourne l'ID de processus afin que vous puissiez vérifier le programme plus tard si vous le souhaitez) afin de ne pas attendre que le programme termine son travail.la source
J'ai le même problème en essayant de me connecter à un terminal 3270 en utilisant le logiciel de script s3270 en Python. Maintenant, je résous le problème avec une sous-classe de Processus que j'ai trouvée ici:
http://code.activestate.com/recipes/440554/
Et voici l'exemple extrait du fichier:
la source
La réponse acceptée est très ancienne.
J'ai trouvé une meilleure réponse moderne ici:
https://kevinmccarthy.org/2016/07/25/streaming-subprocess-stdin-and-stdout-with-asyncio-in-python/
et apporté quelques modifications:
Il est peu probable que les exemples de commandes fonctionnent parfaitement sur votre système et ne gèrent pas les erreurs étranges, mais ce code montre une façon d'exécuter plusieurs sous-processus en utilisant asyncio et de diffuser la sortie.
la source
wait()
directement est obsolèteIl y a plusieurs réponses ici, mais aucune d'entre elles ne répond aux exigences ci-dessous:
Je ne veux pas attendre que la commande se termine ou polluer mon terminal avec des sorties de sous-processus.
Je veux exécuter un script bash avec des redirections.
Je souhaite prendre en charge la tuyauterie dans mon script bash (par exemple
find ... | tar ...
).La seule combinaison qui satisfait aux exigences ci-dessus est:
la source
Ceci est couvert par les exemples de sous- processus Python 3 sous "Attendre que la commande se termine de manière asynchrone":
Le processus commencera à s'exécuter dès que le
await asyncio.create_subprocess_exec(...)
sera terminé. S'il n'est pas terminé au moment où vous appelezawait proc.communicate()
, il y attendra pour vous donner l'état de votre sortie. S'il a terminé,proc.communicate()
reviendra immédiatement.L'essentiel ici est similaire à la réponse de Terrels, mais je pense que la réponse de Terrels semble trop compliquer les choses.
Voir
asyncio.create_subprocess_exec
pour plus d'informations.la source