Estoy tratando de portar un script de shell a la versión de Python mucho más legible. El script de shell original inicia varios procesos (utilidades, monitores, etc.) en segundo plano con "&". ¿Cómo puedo lograr el mismo efecto en Python? Me gustaría que estos procesos no mueran cuando se completen los scripts de Python. Estoy seguro de que está relacionado con el concepto de demonio de alguna manera, pero no pude encontrar cómo hacerlo fácilmente.
295
subprocess.Popen()
es la nueva forma recomendada desde 2010 (estamos en 2015 ahora) y (3) la pregunta duplicada que redirecciona aquí también tiene una respuesta aceptadasubprocess.Popen()
. Saludos :-)subprocess.Popen("<command>")
con el archivo <command> dirigido por un shebang adecuado. Funciona perfecto para mí (Debian) con scripts de bash y python, implícitamente,shell
y sobrevive a su proceso padre.stdout
va a la misma terminal que la de los padres. Entonces, esto funciona de manera muy similar&
a un shell que era una solicitud de OP. Pero el infierno, todas las preguntas se resuelven muy complejo, mientras que un poco de las pruebas mostraron que en ningún momento;)Respuestas:
Nota : esta respuesta es menos actual que cuando se publicó en 2009.
subprocess
Ahora se recomienda usar el módulo que se muestra en otras respuestas en los documentosSi desea que su proceso comience en segundo plano, puede usarlo
system()
y llamarlo de la misma manera que lo hizo su script de shell, o puedespawn
hacerlo:(o, alternativamente, puede probar la
os.P_NOWAIT
bandera menos portátil ).Vea la documentación aquí .
fuente
subprocess
darnos una pista sobre cómo separar un procesosubprocess
?Si bien la solución de jkp funciona, la forma más nueva de hacer las cosas (y la forma en que lo recomienda la documentación) es usar el
subprocess
módulo. Para comandos simples es equivalente, pero ofrece más opciones si desea hacer algo complicado.Ejemplo para su caso:
Esto se ejecutará
rm -r some.file
en segundo plano. Tenga en cuenta que invocar.communicate()
el objeto devuelto desdePopen
se bloqueará hasta que se complete, así que no lo haga si desea que se ejecute en segundo plano:Mira la documentación aquí .
Además, un punto de aclaración: "Fondo" tal como lo usa aquí es puramente un concepto de shell; técnicamente, lo que quieres decir es que quieres generar un proceso sin bloquear mientras esperas a que se complete. Sin embargo, he usado "fondo" aquí para referirme al comportamiento similar a un fondo de shell.
fuente
Popen()
para evitar bloquear el hilo principal y si necesita un demonio, mire elpython-daemon
paquete para comprender cómo debe comportarse un demonio bien definido. Su respuesta está bien si elimina todo lo que comienza con "Pero tenga cuidado", excepto el enlace a los documentos del subproceso.Probablemente desee la respuesta a "Cómo llamar a un comando externo en Python" .
El enfoque más simple es usar la
os.system
función, por ejemplo:Básicamente, lo que pase a la
system
función se ejecutará de la misma manera que si lo hubiera pasado al shell en un script.fuente
Encontré esto aquí :
En Windows (win xp), el proceso padre no finalizará hasta que
longtask.py
haya finalizado su trabajo. No es lo que quieres en el script CGI. El problema no es específico de Python, en la comunidad PHP los problemas son los mismos.La solución es pasar el
DETACHED_PROCESS
Indicador de creación de proceso a laCreateProcess
función subyacente en win API. Si tiene instalado pywin32, puede importar el indicador desde el módulo de proceso win32, de lo contrario, debe definirlo usted mismo:fuente
Úselo
subprocess.Popen()
con elclose_fds=True
parámetro, que permitirá que el subproceso generado se separe del proceso de Python y continúe ejecutándose incluso después de que Python salga.https://gist.github.com/yinjimmy/d6ad0742d03d54518e9f
fuente
Probablemente quiera comenzar a investigar el módulo os para bifurcar diferentes hilos (abriendo una sesión interactiva y emitiendo ayuda (os)). Las funciones relevantes son fork y cualquiera de las ejecutivas. Para darle una idea de cómo comenzar, coloque algo como esto en una función que realice la bifurcación (la función debe tomar una lista o tupla 'args' como argumento que contiene el nombre del programa y sus parámetros; también puede querer para definir stdin, out y err para el nuevo hilo):
fuente
os.fork()
es realmente útil, pero tiene una desventaja notable de solo estar disponible en * nix.threading
: stackoverflow.com/a/53751896/895245 Creo que eso podría funcionar en Windows.Ambos capturan la salida y se ejecutan en segundo plano con
threading
Como se menciona en esta respuesta , si captura la salida con
stdout=
y luego intenta hacerloread()
, el proceso se bloquea.Sin embargo, hay casos en los que necesita esto. Por ejemplo, quería lanzar dos procesos que hablan sobre un puerto entre ellos y guardar su stdout en un archivo de registro y stdout.
El
threading
módulo nos permite hacer eso.Primero, eche un vistazo a cómo hacer la parte de redirección de salida solo en esta pregunta: Python Popen: escriba en stdout y archivo de registro simultáneamente
Luego:
main.py
sleep.py
Despues de correr:
stdout se actualiza cada 0.5 segundos por cada dos líneas que contienen:
y cada archivo de registro contiene el registro respectivo para un proceso determinado.
Inspirado por: https://eli.thegreenplace.net/2017/interacting-with-a-long-running-child-process-in-python/
Probado en Ubuntu 18.04, Python 3.6.7.
fuente