python - Lanzar un proceso completamente independiente
python-2.7 subprocess (3)
No pude ver ningún proceso en ejecución.
No ve ningún proceso en ejecución porque el proceso de
python
hijo se cierra inmediatamente.
Los argumentos de
Popen
son incorrectos, como
dice user4815162342 en el comentario
.
Para iniciar un proceso
completamente independiente
, puede usar el
paquete
python-daemon
o systemd / supervisord / etc:
#!/usr/bin/python25
import daemon
from long_process import main
with daemon.DaemonContext():
main()
Aunque podría ser suficiente en su caso, para comenzar el niño con argumentos de
Popen
correctos:
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 el proceso secundario no requiere
python2.5
entonces podría usar
sys.executable
en
sys.executable
lugar (para usar la misma versión de Python que la principal).
Nota: el código cierra
DEVNULL
en el padre sin esperar a que finalice el proceso hijo (no tiene ningún efecto en el hijo).
Quiero iniciar un proceso desde mi script de python
main.py
Específicamente, quiero ejecutar el siguiente comando:
`nohup python ./myfile.py &`
y el archivo
myfile.py
debería continuar ejecutándose, incluso después de que
main.py
script
main.py
También deseo obtener el
pid
del nuevo proceso.
Lo intenté:
-
os.spawnl*
-
os.exec*
-
subprocess.Popen
y todos están terminando
myfile.py
cuando sale el script
main.py
Actualización:
¿Puedo usar
os.startfile
con
xdg-open
?
¿Es el enfoque correcto?
Ejemplo
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 reviso
ps aux | grep long_process
ps aux | grep long_process
, no hay proceso en ejecución.
long_process.py que sigue imprimiendo texto: sin salida.
¿Estoy haciendo algo mal aquí?
Abre su proceso de larga duración y
mantiene una tubería
.
Entonces esperas hablar con él.
Cuando su script de inicio se cierra, ya no puede hablar con él.
El proceso de larga duración recibe un
SIGPIPE
y sale.
Lo siguiente simplemente funcionó para mí (Linux, Python 2.7).
Crea un ejecutable de larga ejecución:
$ echo "sleep 100" > ~/tmp/sleeper.sh
Ejecute 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
Salga de REPL y vea que el proceso aún se está ejecutando:
>>> ^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 primero desea comunicarse con el proceso iniciado y luego dejarlo solo para que se ejecute más, tiene algunas opciones:
-
Maneje
SIGPIPE
en su proceso de larga duración, no muera en él. Vive sin stdin después de que finalice el proceso del iniciador. - Pase lo que quiera usando argumentos, entorno o un archivo temporal.
- Si desea una comunicación bidireccional, considere usar una tubería con nombre ( man mkfifo ) o un socket, o escribir un servidor adecuado.
- Haga la bifurcación del proceso de larga duración después de que se haya completado la fase de comunicación bidireccional inicial.
Puede usar
os.fork()
.
import os
pid=os.fork()
if pid==0: # new process
os.system("nohup python ./myfile.py &")
exit()
# parent process continues