Je voulais lancer un processus à partir de mon python (main.py)
, en particulier, je veux exécuter la commande ci-dessous
`Nohup python ./myfile.py &`
et ce fichier myfile.py
devrait même après la sortie de mon script principal python.
De plus, je souhaite obtenir le pid
du nouveau processus.
J'ai essayé os.spawnl*
, os.exec*
& subprocess.Popen
méthodes, toutes mettent fin à mon myfile.py
si mon script main.py se termine.
Il me manque peut-être quelque chose.
Mise à jour: puis-je utiliser os.startfile
avec xdg-open
? Est-ce une bonne approche?
Exemple
a = subprocess.Popen([sys.executable, "Nohup /usr/bin/python25 /long_process.py &"],\
stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
print a.pid
Si je vérifie ps aux | grep long_process
, Je n'ai vu aucun processus en cours d'exécution.
long_process.py qui continue d'imprimer du texte: pas de sortie.
Suis-je en train de faire quelque chose de mal ici?
Vous ouvrez votre processus de longue durée et gardez un tuyau vers lui . Vous vous attendez donc à lui en parler. Lorsque votre script de lanceur se termine, vous ne pouvez plus lui parler. Le processus de longue durée reçoit un SIGPIPE
et se termine.
Ce qui suit vient de fonctionner pour moi (Linux, Python 2.7).
Créez un exécutable de longue durée:
$ echo "sleep 100" > ~/tmp/sleeper.sh
Exécutez Python REPL:
$ python
>>>
import subprocess
import os
p = subprocess.Popen(['/bin/sh', os.path.expanduser('~/tmp/sleeper.sh')])
# look ma, no pipes!
print p.pid
# prints 29893
Quittez le REPL et voyez le processus toujours en cours:
>>> ^D
$ ps ax | grep sleeper
29893 pts/0 S 0:00 /bin/sh .../tmp/sleeper.sh
29917 pts/0 S+ 0:00 grep --color=auto sleeper
Si vous souhaitez d'abord communiquer avec le processus démarré puis le laisser tranquille pour continuer, vous avez quelques options:
SIGPIPE
dans votre processus de longue haleine, ne mourez pas dessus. Vivez sans stdin après la fin du processus du lanceur.Vous pouvez utiliser os.fork()
.
import os
pid=os.fork()
if pid==0: # new process
os.system("Nohup python ./myfile.py &")
exit()
# parent process continues
Je ne pouvais voir aucun processus en cours d'exécution.
Aucun processus n'est en cours d'exécution car le processus enfant python
se ferme immédiatement. Les arguments Popen
sont incorrects car l'utilisateur4815162342 dit dans le commentaire .
Pour lancer un processus complètement indépendant , vous pouvez utiliser python-daemon
package ou utilisez systemd/supervisord/etc:
#!/usr/bin/python25
import daemon
from long_process import main
with daemon.DaemonContext():
main()
Bien que cela puisse suffire dans votre cas, pour démarrer l'enfant avec les arguments Popen
corrects:
with open(os.devnull, 'r+b', 0) as DEVNULL:
p = Popen(['/usr/bin/python25', '/path/to/long_process.py'],
stdin=DEVNULL, stdout=DEVNULL, stderr=STDOUT, close_fds=True)
time.sleep(1) # give it a second to launch
if p.poll(): # the process already finished and it has nonzero exit code
sys.exit(p.returncode)
Si le processus enfant ne nécessite pas python2.5
alors vous pouvez utiliser sys.executable
à la place (pour utiliser la même version Python version que le parent).
Remarque: le code ferme DEVNULL
dans le parent sans attendre la fin du processus enfant (il n'a aucun effet sur l'enfant).