J'essaie de porter un script shell vers la version python beaucoup plus lisible. Le script shell d'origine démarre plusieurs processus (utilitaires, moniteurs, etc.) en arrière-plan avec "&". Comment puis-je obtenir le même effet en python? J'aimerais que ces processus ne meurent pas lorsque les scripts python sont terminés. Je suis sûr que cela est lié au concept de démon d'une manière ou d'une autre, mais je n'ai pas trouvé comment le faire facilement.
295
subprocess.Popen()
est la nouvelle méthode recommandée depuis 2010 (nous sommes en 2015 maintenant) et (3) la redondance des questions dupliquées ici a également une réponse acceptéesubprocess.Popen()
.subprocess.Popen("<command>")
avec un fichier <command> dirigé par un shebang approprié. Fonctionne parfaitement pour moi (Debian) avec des scripts bash et python, implicitementshell
et survit à son processus parent.stdout
va au même terminal que celui du parent. Donc, cela fonctionne un peu comme&
dans un shell qui était une demande OP. Mais bon sang, toutes les questionsRéponses:
Remarque : Cette réponse est moins actuelle qu'elle ne l'était lors de sa publication en 2009. L'utilisation du
subprocess
module montré dans d'autres réponses est maintenant recommandée dans la documentationSi vous voulez que votre processus démarre en arrière-plan, vous pouvez soit l'utiliser
system()
et l'appeler de la même manière que votre script shell, soit le fairespawn
:(ou, alternativement, vous pouvez essayer le
os.P_NOWAIT
drapeau moins portable ).Voir la documentation ici .
la source
subprocess
nous donner un indice sur la façon de détacher un processussubprocess
?Alors que la solution de jkp fonctionne, la nouvelle façon de faire les choses (et la manière recommandée par la documentation) est d'utiliser le
subprocess
module. Pour les commandes simples, son équivalent, mais il offre plus d'options si vous voulez faire quelque chose de compliqué.Exemple pour votre cas:
Cela s'exécutera
rm -r some.file
en arrière-plan. Notez que l'appel.communicate()
à l'objet renvoyé depuisPopen
sera bloqué jusqu'à ce qu'il se termine, alors ne le faites pas si vous voulez qu'il s'exécute en arrière-plan:Voir la documentation ici .
Aussi, un point de clarification: "Contexte" tel que vous l'utilisez ici est purement un concept shell; techniquement, ce que vous voulez dire, c'est que vous voulez lancer un processus sans le bloquer pendant que vous attendez qu'il se termine. Cependant, j'ai utilisé «arrière-plan» ici pour faire référence à un comportement semblable à un arrière-plan du shell.
la source
Popen()
pour éviter de bloquer le thread principal et si vous avez besoin d'un démon, regardez lepython-daemon
paquet pour comprendre comment un démon bien défini doit se comporter. Votre réponse est correcte si vous supprimez tout en commençant par "Mais méfiez-vous" à l'exception du lien vers les documents des sous-processus.Vous voulez probablement la réponse à "Comment appeler une commande externe en Python" .
L'approche la plus simple consiste à utiliser la
os.system
fonction, par exemple:Fondamentalement, tout ce que vous transmettez à la
system
fonction sera exécuté de la même manière que si vous l'aviez transmis au shell dans un script.la source
J'ai trouvé ça ici :
Sous Windows (win xp), le processus parent ne se terminera pas tant qu'il n'aura pas
longtask.py
terminé son travail. Ce n'est pas ce que vous voulez dans le script CGI. Le problème n'est pas spécifique à Python, dans la communauté PHP les problèmes sont les mêmes.La solution consiste à passer l'
DETACHED_PROCESS
indicateur de création de processus à laCreateProcess
fonction sous-jacente dans l'API win. Si vous avez installé pywin32, vous pouvez importer le drapeau du module win32process, sinon vous devez le définir vous-même:la source
À utiliser
subprocess.Popen()
avec leclose_fds=True
paramètre, qui permettra au sous-processus généré d'être détaché du processus Python lui-même et de continuer à s'exécuter même après la fermeture de Python.https://gist.github.com/yinjimmy/d6ad0742d03d54518e9f
la source
Vous voudrez probablement commencer à étudier le module os pour forder différents threads (en ouvrant une session interactive et en émettant de l'aide (os)). Les fonctions pertinentes sont fork et n'importe laquelle des fonctions exec. Pour vous donner une idée sur la façon de commencer, mettez quelque chose comme ça dans une fonction qui exécute le fork (la fonction doit prendre une liste ou un tuple 'args' comme argument qui contient le nom du programme et ses paramètres; vous pouvez également vouloir pour définir stdin, out et err pour le nouveau thread):
la source
os.fork()
est vraiment utile, mais il a un inconvénient notable d'être uniquement disponible sur * nix.threading
: stackoverflow.com/a/53751896/895245 Je pense que cela pourrait fonctionner sous Windows.Les deux capturent la sortie et fonctionnent en arrière-plan avec
threading
Comme mentionné dans cette réponse , si vous capturez la sortie avec
stdout=
puis essayez de le faireread()
, les blocs de processus.Cependant, il y a des cas où vous en avez besoin. Par exemple, je voulais lancer deux processus qui parlent sur un port entre eux et enregistrer leur stdout dans un fichier journal et stdout.
Le
threading
module nous permet de le faire.Tout d'abord, regardez comment faire la partie de redirection de sortie seule dans cette question: Python Popen: Ecrivez simultanément sur stdout ET dans le fichier journal
Ensuite:
main.py
sleep.py
Après l'exécution:
stdout est mis à jour toutes les 0,5 secondes pour chaque ligne contenant:
et chaque fichier journal contient le journal correspondant pour un processus donné.
Inspiré par: https://eli.thegreenplace.net/2017/interacting-with-a-long-running-child-process-in-python/
Testé sur Ubuntu 18.04, Python 3.6.7.
la source