¿Cómo ejecutar un script de Python en segundo plano incluso después de cerrar la sesión SSH?

110

Tengo un script de Python bgservice.pyy quiero que se ejecute todo el tiempo, porque es parte del servicio web que construyo. ¿Cómo puedo hacer que se ejecute de forma continua incluso después de cerrar la sesión SSH?

zihaoyu
fuente

Respuestas:

213

Ejecutar nohup python bgservice.py &para que el script ignore la señal de colgar y siga funcionando. La salida se incluirá nohup.out.

Idealmente, ejecutaría su script con algo como supervisepara que pueda reiniciarse si (cuando) muere.

Edward Dale
fuente
15
cuando ejecuto el comando con nohup y &, nohup: ignoring in put and appending output to aparece el mensaje nohup.out'` y cuando presiono enter, el proceso sale con el estado 1. ¿Qué está pasando?
Santosh Ghimire
1
leer la salida en nohup.out. en mi caso, fue un problema de permisos, necesitaba usar sudo
mxns
y ¿cómo detener el bgservice después de que se ejecute en este método?
fuego en el hoyo
1
@Shaegorath guarda el pid en algún lugar para que puedas enviar señales al proceso más tarde. en algunos shells (bash, zsh, etc.) después de hacerlo somecommand &, imprimirá el pid como [1] 12345. de lo contrario, puede usar $!.
Tony Beta Lambda
31

Si ya ha iniciado el proceso y no desea eliminarlo y reiniciarlo sin previo aviso, puede enviarlo a un segundo plano y luego rechazarlo.

Ctrl+Z (suspender el proceso)

bg (reinicia el proceso en segundo plano

disown %1(asumiendo que este es el trabajo n. ° 1, use jobspara determinar)

cobre
fuente
17

También puede usar la pantalla GNU que casi todos los sistemas Linux / Unix deberían tener.

Si está en Ubuntu / Debian, su variante mejorada byobu también es bastante agradable.

Dirk Eddelbuettel
fuente
12

Podría considerar convertir su script de Python en un demonio de Python adecuado, como se describe aquí .

Python-demonio es una buena herramienta que se puede usar para ejecutar scripts de Python como un proceso de demonio en segundo plano en lugar de un script de ejecución permanente. Necesitará modificar un poco el código existente, pero es simple y llanamente.

Si tiene problemas con python-daemon, hay otro supervisor de utilidad que hará lo mismo por usted, pero en este caso no tendrá que escribir ningún código (o modificar el existente) ya que esta es una solución lista para usar para demonizar Procesos.

Dustin Kirkland
fuente
dar una breve explicación acerca de cómo se puede resolver el problema es generalmente una buena idea.
Nikhil Sahu
7

No puedes hacerlo, pero prefiero la pantalla .

Randy Proctor
fuente
5

Aquí hay una solución simple dentro de Python usando un decorador:

import os, time

def daemon(func):
    def wrapper(*args, **kwargs):
        if os.fork(): return
        func(*args, **kwargs)
        os._exit(os.EX_OK)
    return wrapper

@daemon
def my_func(count=10):    
  for i in range(0,count):
     print('parent pid: %d' % os.getppid())
     time.sleep(1)


my_func(count=10)
#still in parent thread
time.sleep(2)
#after 2 seconds the function my_func lives on is own

Por supuesto, puede reemplazar el contenido de su bgservice.pyarchivo en lugar de my_func.

Chouettou
fuente
1
Quizás sea necesario captar la señal SIGHUP. Luego agregue signal.signal (signal.SIGHUP, handler) en su bloque.
Chouettou
3

El shell zsh tiene una opción para hacer que todos los procesos en segundo plano se ejecuten con nohup.

En ~/.zshrcagregue las líneas:

setopt nocheckjobs  #don't warn about bg processes on exit
setopt nohup        #don't kill bg processes on exit

Entonces solo necesita ejecutar un proceso como este:, python bgservice.py &y ya no necesita usar el comando nohup.

Sé que no mucha gente usa zsh, pero es un shell realmente genial que recomendaría.

jonescb
fuente
1

Si lo que necesita es que el proceso se ejecute para siempre, sin importar si ha iniciado sesión o no, considere ejecutar el proceso como un demonio.

supervisord es una excelente solución lista para usar que se puede usar para demonizar cualquier proceso. Tiene otra utilidad controladorasupervisorctl que puede usarse para monitorear los procesos que está ejecutando el supervisor.

No tiene que escribir ningún código adicional ni modificar los scripts existentes para que esto funcione. Además, la documentación detallada hace que este proceso sea mucho más sencillo.

Después de rascarme la cabeza durante horas con python-daemon, supervisor es la solución que funcionó para mí en minutos.

Espero que esto ayude a alguien que intente hacer que Python-daemon funcione

Nikhil Sahu
fuente
1

También puede utilizar Yapdi :

Uso básico:

import yapdi

daemon = yapdi.Daemon()
retcode = daemon.daemonize()

# This would run in daemon mode; output is not visible
if retcode == yapdi.OPERATION_SUCCESSFUL:
print('Hello Daemon')
Victor Mendonça Nogueira
fuente
1

Prueba esto:

nohup python -u <your file name>.py >> <your log file>.log &

Puede ejecutar el comando anterior en la pantalla y salir de la pantalla.

Ahora puede rastrear los registros de su secuencia de comandos de Python mediante: tail -f <your log file>.log

Para matar su script, puede usar los comandos ps -aux y kill .

Sushil Verma
fuente