Esta reseña ha sido evaluado por expertos para asegurar la veracidad de esta noticia.
Solución:
Abres tu proceso de ejecución prolongada y mantener una pipa a ella. Así que esperas hablar con él. Cuando se cierra el script de inicio, ya no puede hablar con él. El proceso de larga duración recibe una SIGPIPE
y salidas.
Lo siguiente me funcionó (Linux, Python 2.7).
Crea un ejecutable de larga duració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 desea comunicarse primero con el proceso iniciado y luego dejarlo solo para continuar, tiene algunas opciones:
- Resolver
SIGPIPE
en su proceso de larga duración, no muera en él. En vivo 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 canalización con nombre (man mkfifo) o un socket, o escribir un servidor adecuado.
- Haga que el proceso de ejecución prolongada se bifurque después de que se complete la fase de comunicación bidireccional inicial.
Puedes usar os.fork()
.
import os
pid=os.fork()
if pid==0: # new process
os.system("nohup python ./myfile.py &")
exit()
# parent process continues
No pude ver ningún proceso en ejecución.
No ve ningún proceso ejecutándose porque el niño python
el proceso sale inmediatamente. los Popen
los argumentos son incorrectos como dice el usuario 4815162342 en el comentario.
para lanzar un completamente independiente proceso, podrías usar python-daemon
paquete o use 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, iniciar al niño con las Popen
argumentos:
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 hijo no requiere python2.5
entonces podrías usar sys.executable
en su lugar (para usar la misma versión de Python que el padre).
Nota: el código se cierra DEVNULL
en el padre sin esperar a que termine el proceso hijo (no tiene efecto en el hijo).
Aquí tienes las comentarios y valoraciones
Si te ha sido de provecho este post, sería de mucha ayuda si lo compartes con más seniors y nos ayudes a dar difusión a nuestro contenido.