Mantener un proceso de Linux ejecutándose después de cerrar sesión

142

Me estoy conectando a una máquina Linux a través de SSH, y estoy tratando de ejecutar un script bash pesado que realice operaciones del sistema de archivos. Se espera que siga funcionando durante horas, pero no puedo dejar abierta la sesión SSH debido a los problemas de conexión a Internet que tengo.

Dudo que ejecutar el script con el operador de fondo, el ampersand ( &), sea suficiente, porque lo probé y luego descubrí que el proceso no se completó. ¿Cómo puedo cerrar sesión y mantener el proceso en ejecución?

doc_id
fuente

Respuestas:

135

El mejor método es iniciar el proceso en un multiplexor terminal. Alternativamente, puede hacer que el proceso no reciba la señal HUP.


Un multiplexor de terminales proporciona terminales "virtuales" que se ejecutan independientemente del terminal "real" (en realidad, todos los terminales actuales son "virtuales", pero ese es otro tema para otro día). El terminal virtual seguirá funcionando incluso si su terminal real está cerrada con su sesión ssh.

Todos los procesos iniciados desde la terminal virtual seguirán ejecutándose con esa terminal virtual. Cuando se vuelve a conectar al servidor, puede volver a conectarse a la terminal virtual y todo será como si nada hubiera pasado, salvo el tiempo transcurrido.

Dos multiplexores de terminal populares son screen y tmux .

La pantalla tiene una curva de aprendizaje empinada. Aquí hay un buen tutorial con diagramas que explican el concepto: http://www.ibm.com/developerworks/aix/library/au-gnu_screen/


La señal HUP (o SIGHUP) es enviada por el terminal a todos sus procesos secundarios cuando el terminal está cerrado. La acción común al recibir SIGHUP es terminar. Por lo tanto, cuando su sesión ssh se desconecte, todos sus procesos finalizarán. Para evitar esto, puede hacer que sus procesos no reciban SIGHUP.

Dos métodos sencillos para hacerlo son nohupy disown.

Para obtener más información sobre cómo nohupy cómo disownfunciona, lea esta pregunta y respuesta: https://unix.stackexchange.com/questions/3886/difference-between-nohup-disown-and

Nota: aunque los procesos seguirán ejecutándose, ya no podrá interactuar con ellos porque ya no están conectados a ningún terminal. Este método es principalmente útil para procesos por lotes de larga ejecución que, una vez iniciados, ya no necesitan ninguna entrada del usuario.

lesmana
fuente
3
Me gusta esta respuesta, ya que proporciona una solución para situaciones interactivas y no interactivas. En el caso interactivo, screenle ofrece muchas más opciones, pero si está utilizando authorized_keyspara permitir que las personas ejecuten un script de forma remota ssh, la nohupopción es una manera simple y agradable para que el script inicie procesos que duran más que la sshsesión utilizada para iniciarlos. .
Mark Booth
1
@rahmanisback - Recuerde que puede cambiar su respuesta aceptada en cualquier momento. El hecho de que hasta ahora la respuesta de EricA sea muy votada no significa que sea la mejor respuesta para usted, de hecho, hacerla su respuesta aceptada puede alentar a más personas a votarla como una buena respuesta.
Mark Booth
3
* tos * tmuxisbetter * tos *
crasic
3
tmux > pantalla. Pruébalo, nunca volverás.
h0tw1r3
1
@TheLQ - byobu es GNU Screen. Todavía estás usando la pantalla, solo con un .screenrc altamente personalizado.
EEAA
92

Hay algunas maneras de hacer esto, pero la que encuentro más útil es usar GNU Screen .

Después de entrar, corre screen. Esto iniciará otro shell que se ejecuta dentro de la pantalla. Ejecute su comando, luego haga un Ctrl- a d.

Esto lo "desconectará" de la sesión de pantalla. En este punto, puede cerrar sesión o hacer cualquier otra cosa que desee.

Cuando desee volver a conectarse a la sesión de pantalla, simplemente ejecute screen -RDdesde el indicador de comandos de shell (como el mismo usuario de uso que creó la sesión).

EEAA
fuente
66
La pantalla tiene un montón de comandos, todos comenzando con Ctrl-a. Si solo aprende un extra, comience con "Ctrl-a?". Entonces no querrás aprender "Ctrl-a c" y "Ctrl-a n"
olafure
@olafure +1, gracias. Parece que Screen va a ser mi caja de herramientas principal.
doc_id
tmux > pantalla. Pruébalo, nunca volverás.
h0tw1r3
+1 para tmux. Renuncié a la pantalla hace 5 semanas.
Bryan Hunt
73

En bash, la disownpalabra clave se adapta perfectamente a esto. Primero, ejecute su proceso en segundo plano (use &o ^Zluego escriba bg):

$ wget --quiet http://server/some_big_file.zip &
[1] 1156

Al escribir jobspuede ver que el proceso todavía es propiedad del shell:

$ jobs
[1]+  Running  wget

Si tuviera que cerrar sesión en este punto, la tarea en segundo plano también sería eliminada. Sin embargo, si ejecuta disown, bash separa el trabajo y permite que continúe ejecutándose:

$ disown

Puedes confirmar esto:

$ jobs
$ logout

Incluso puede combinar el &y disownen la misma línea, como:

$ wget --quiet http://server/some_big_file.zip & disown
$ logout

Esto es mejor que correr nohupen mi opinión porque no deja nohup.outarchivos llenos de basura en todo el sistema de archivos. Además, nohupdebe ejecutarse antes de ejecutar el comando; disownse puede utilizar si solo decide más adelante que desea realizar un segundo plano y separar la tarea.

Jeremy Visser
fuente
1
Esa es una muy buena respuesta, 1+. La única preferencia para nohup o Screen sería la independencia de bash, y podría usarse con otro shell. Pero me atendré a tu enfoque cada vez que use bash.
doc_id
Sí, esto es específico de bash, ya que bash es el único shell que he usado. Me pregunto si otros shells admiten algo similar (es decir, lanzarse en segundo plano sin nohup): sería fantástico si alguien pudiera publicar otras respuestas para otros shells.
Jeremy Visser
1
vea mi respuesta que muestra cómo hacerlo con cualquier sh-lookalike
w00t
1
+1 por poder decidir más tarde. Justo en este momento tenía una necesidad de esto. funcionó como se anuncia
code_monk
37

La herramienta nohup, disponible en la mayoría de las cajas de Linux hará esto.

Korjavin Ivan
fuente
1
Esta es, con mucho, la respuesta más simple. Cualquier salida de se dirige automáticamente a nohup.out y se puede examinar más adelante.
Julian
3
nohup no requiere zsh en absoluto.
Aaron Brown
nohup es la respuesta correcta, es la abreviatura de no colgar.
Kinjal Dixit
2
nohup se encuentra en muchas más máquinas que la pantalla, por lo que debe saber cómo usarlo.
Zenon
27

Solo para ser minucioso, señalaré tmux , que tiene la misma idea básica que la pantalla:

tmux está destinado a ser una alternativa moderna con licencia BSD a programas como la pantalla GNU. Las características principales incluyen:

  • Una interfaz de comandos potente, coherente, bien documentada y fácilmente programable.
  • Una ventana puede dividirse horizontal y verticalmente en paneles.
  • Los paneles se pueden mover y redimensionar libremente, o organizar en diseños preestablecidos.
  • Soporte para terminales UTF-8 y 256 colores.
  • Copie y pegue con múltiples buffers.
  • Menús interactivos para seleccionar ventanas, sesiones o clientes.
  • Cambie la ventana actual buscando texto en el objetivo.
  • Bloqueo de terminal, manual o después de un tiempo de espera.
  • Una base de código limpia, fácil de extender y con licencia BSD, en desarrollo activo.

Sin embargo, es aproximadamente infinitamente más fácil de buscar en Google.

Manitas5
fuente
2
Usar "gnu screen"como su consulta de búsqueda funciona bastante bien.
gnur
44
+1000 para tmux!
mbq
11

La pantalla es exagerada para mantener los procesos en ejecución cuando cierra la sesión.

Prueba dtach :

dtach es un programa escrito en C que emula la función de desconexión de la pantalla, lo que permite que un programa se ejecute en un entorno protegido del terminal de control. Por ejemplo, el programa bajo el control de dtach no se vería afectado por la desconexión del terminal por alguna razón.

dtach fue escrito porque la pantalla no satisfacía adecuadamente mis necesidades; No necesitaba las funciones adicionales de la pantalla, como el soporte para múltiples terminales o el soporte de emulación de terminal. La pantalla también era demasiado grande, voluminosa y tenía un código fuente difícil de entender.

screen también interfirió con mi uso de aplicaciones de pantalla completa como emacs e ircII, debido a su interpretación excesiva de la transmisión entre el programa y los terminales conectados. dtach no tiene una capa de emulación de terminal y pasa el flujo de salida sin formato del programa a los terminales conectados. El único procesamiento de entrada que realiza dtach es buscar el carácter de desconexión (que le indica a dtach que se desconecte del programa) y procesar la clave de suspensión (que le dice a dtach que se suspenda temporalmente sin afectar el programa en ejecución), y ambos pueden deshabilitarse si lo desea.

Contrariamente a la pantalla, dtach tiene características mínimas y es extremadamente pequeño. Esto permite que dtach sea auditado más fácilmente para detectar errores y agujeros de seguridad, y lo hace accesible en entornos donde el espacio es limitado, como en los discos de rescate.

sml
fuente
Gracias. Vine aquí solo para publicar sobre dtach también. Es mi cosa favorita para el desprendimiento de terminales ahora; La pantalla hace demasiado, e interfiere con la entrada en un grado ridículo. El hecho de que la pantalla necesite su propia tapa de término es bastante inquietante.
esponjoso
9

Aquí hay una manera de demonizar cualquier proceso de shell, no se necesitan programas externos:

( while sleep 5; do date; done ) <&- >output.txt &

Cuando cierre su sesión, el trabajo continuará ejecutándose como lo demuestra el archivo output.txt (que tiene almacenamiento en búfer, por lo que lleva un tiempo mostrar que no es cero). No olvides matar tu trabajo después de la prueba.

Entonces, todo lo que necesita hacer es cerrar la entrada estándar y poner en segundo plano el trabajo. Para ser realmente bueno, primero cd /para no aferrarte a una montura.

Esto funciona incluso en sh simple bajo Solaris.

w00t
fuente
Interesante. Que surgieron algunas preguntas notables. Puedo ver que configura el STDIN a nada, el -operador? ¿Cuál es la diferencia entre < /dev/nully &-? Supongo que a STDIN (y a otros STDOUT y STDERR) se les podría asignar un archivo < fileo una transmisión <& streamen caso de STDIN. ¿Sería lo mismo usando < /dev/nullen su ejemplo anterior? ¿Y el operador -anterior se refiere a un nulo como la secuencia?
doc_id
Cuando haces x <& -, eso cierra el descriptor de archivo x. En este caso no hay x, lo que hace que bash esté predeterminado en 1, es decir, entrada estándar. Si usa </ dev / null no está cerrando stdin, solo está dando un archivo vacío al programa como entrada.
w00t
1
Y para ser honesto, realmente no sé por qué esto demoniza lo que estás ejecutando :-) Sin embargo, funciona, lo usamos en la producción. Lo descubrí mientras jugaba con la esperanza de poder demonizar un proceso en shell sin necesitar nada especial, así que comencé cerrando stdin y eso fue suficiente. Debería ir a leer algunas fuentes de shell, pero supongo que si cierra stdin y en segundo plano el proceso, también se separa el proceso.
w00t
2
Creo que la razón es que un SIGHUP (la señal real que hace que el niño se cierre cuando el shell muere) se activa cuando un proceso padre cierra el controlador stdin de su hijo. Sin embargo, si stdin comienza como nulo, en lugar de cerrarse después del hecho, no hay forma de que el padre active el SIGHUP. Buen hallazgo, sin embargo, nunca habría pensado en eso.
Jeremy Visser
@JeremyVisser que suena realmente plausible!
w00t
7

El atcomando puede ser útil para este tipo de situación. Por ejemplo, escriba:

at now

Y luego puede ingresar un comando o una serie de comandos que se ejecutarán. Los resultados deben ser enviados por correo electrónico si el correo electrónico está configurado correctamente en la máquina.

En lugar de now, puede especificar una hora opcionalmente con una fecha o una expresión de hora como now + 15 minutes. Ver man atpara más detalles.

rjmunro
fuente
7

byobuen Ubuntu es un buen front-end para la pantalla. Al presionar Ctrl, ?obtienes una lista de todos los atajos de teclado. Agrega una barra de estado que puede ser útil para ver la carga de la CPU, el espacio en disco, etc. En general, proporciona una experiencia que describiría como una conexión VNC basada en terminal.

nohup permite iniciar un trabajo en segundo plano con su salida enrutada a un archivo de registro, que siempre se puede redirigir a / dev / null si no es necesario.

John Beckett
fuente