Evite que la tarea de Linux actualmente en ejecución se elimine después de cerrar sesión en SSH


18

Tengo una tarea computacional que se ejecuta durante unos días en un servidor Linux a través de una conexión SSH. No está en segundo plano, por lo que la conexión SSH está en espera de la tarea.

Quiero reiniciar la máquina local (no el servidor) desde la que he abierto la sesión ssh, pero quiero mantener la tarea en ejecución. ¿Es eso posible?

Respuestas:


22

Si su tarea ya está en marcha, ya es demasiado tarde *para considerar soluciones alternativas que insertar una capa adicional entre su sshsesión y la cáscara de la ejecución del comando, como screen, tmux, byobu, nohupy los gustos.

Si el soporte de procesos para ser colocado en el fondo y en particular no se cuelga cuando stdouty stderrno son modificables / cerrado, se puede poner en el fondo antes de salir con el ControlZy bgluego separarla de su cáscara con la disownorden interna.

p.ej:

$ ssh localhost
You have new mail.
Last login: Fri Jun  6 11:26:56 2014

$ /bin/sleep 3600    


^Z[1] + Stopped                  /bin/sleep 3600
$ bg
[1] /bin/sleep 3600&
$ jobs
[1] +  Running                 /bin/sleep 3600
$ disown %1
$ exit
Connection to localhost closed.
$ ps -ef|grep sleep
jlliagre 12864     1  0 21:12 ?        00:00:00 /bin/sleep 3600
jlliagre 13056 12477  0 21:13 pts/18   00:00:00 grep sleep
$ 

*Como comentó Bob, en realidad hay varias formas hack para reparar una sesión tty en Linux. repty, retty , injcode y neercs . Las apariencias más avanzadas son reptyr, pero es posible que necesite privilegios de root para permitir que ptrace piratee su proceso.


Usé Ctrl + Z, el trabajo se detuvo y se movió a segundo plano, luego realicé el disowncomando. Regresó: bash: advertencia: eliminar el trabajo 1 detenido con el grupo de procesos 24876. Ahora mi trabajo aparece en la lista ps -allpero parece que no funciona (el uso de la CPU es 0%)
Ali

Parece que mi proceso se ha detenido. Supongo que debería haber proporcionado la identificación del proceso con el disowncomando
Ali

@ Ali Creo que olvidó ejecutar el comando bg para reanudar el trabajo suspendido.
Jason Zhu

1
@JasonZhu Gracias por señalar eso. No estaba claro si bgse requería el comando en la primera parte de mi respuesta. Editado
jlliagre 03 de

2
Si olvidó el comando bg y solo ejecutó el comando disown, debería poder ejecutar el proceso nuevamente, lo kill -CONTque hace aproximadamente lo mismo que lo haría bg.
kasperd el

5

Una solución es usar la pantalla GNU . Puede iniciar screen, ejecutar su comando y luego desconectarse con C-a d. Más tarde, para volver a conectar, hazlo screen -ry estarás de vuelta en tu sesión anterior.

Otros beneficios de la pantalla son la administración de ventanas (para que pueda cambiar a otros shells mientras se ejecuta su comando, sin necesidad de una nueva conexión SSH), y permite que su comando permanezca en primer plano, ya sea en la sesión actual o en una posterior.

Editar: como se señaló en los comentarios, esto solo funcionará si recuerda comenzar screenantes de ejecutar el comando. Si el comando ya se está ejecutando, necesitará la solución de @ jlliagre.


2
tmuxes otro programa como screenese que le permite tener una sesión remota que no está vinculada a su conexión SSH actual.
Darth Android

2
Tu solución es genial. Sin embargo, no se ajusta completamente a mi pregunta: pregunté sobre el proceso que se está ejecutando actualmente, no sobre un proceso que se ejecutará en el futuro screen.
Ali

Ah bien. En ese caso, creo que necesitará usar la solución de @ jlliagre. (Hasta donde yo sé, no hay una manera de conectar un proceso que ya se está ejecutando a algo como screeno tmux.)
Scott Weldon

1

Una de las formas "estándar" de hacerlo es usar el nohupcomando, incluido en coreutils, como este:

nohup COMMAND [ARGS] &

Pero el comando redirigirá la salida ( STDOUT& STDERRAFAIK) del programa a un archivo nohup.out, haciéndolo de alguna manera molesto a veces (como generar un archivo de registro enorme), por lo que es posible que desee hacer su propia redirección o redirigirla a / dev / null si tu quieres.


2
Lea de nuevo. El proceso ya se está ejecutando .
Lightness compite con Monica el

/ avergonzado no leyó con cuidado. Lo siento.
wangguoqin1001

En realidad nohupse puede usar para esto. Simplemente suspenda el proceso de ejecución y envíelo a segundo plano ( Ctrl+ Zy ejecutar bg) y luego puede emitir nohup %1.
Mike

0

Además nohup, puede iniciar el proceso en segundo plano utilizando "&" y subshell:

Sufije el comando con & y envuélvalo entre paréntesis

$ (thecommand args &)

Digamos que su proceso gana el pid 1922:

$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
usr      11473  2643  0 15:07 pts/1    00:00:00 bash
usr      11922     1  0 15:11 pts/1    00:00:00 thecommand

Mire que no está conectado al proceso de shell 11473, que era su padre original. Por lo tanto, si sale o elimina el shell actual (11473), el proceso 11922 seguirá ejecutándose y se desconectará de los pts.

Intente salir del shell e ingrese un nuevo shell. Incluso si este shell está conectado a los mismos pts, puede ver el proceso ahora sin un pts:

$ ps -fp 11922
UID        PID  PPID  C STIME TTY          TIME CMD
usr      11922     1  0 15:11 ?        00:00:00 thecommand

No sé cómo se llama o documenta en Posix, pero lo uso de esta manera desde 1990 en bsh, ksh y ahora en bash.

Por último, puede usar el bgcomando de shell incorporado:

Simplemente inicie su programa y si decide pausarlo, o planea mantenerlo en segundo plano, escriba CTRL + Z:

$ thecommand
^Z
[1] Stopped          thecommand

Ahora deje que continúe ejecutándose en segundo plano:

$ bg
[1]+ thecommand &

Si observa la información del proceso, todavía tiene un proceso padre:

$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
usr      12046  2643  0 15:18 pts/6    00:00:00 bash
usr      12571 12046  0 16:00 pts/6    00:00:00 thecommand
usr      12601 12046  0 16:04 pts/6    00:00:00 ps -f

Entonces, salga del proceso actual. El proceso de ejecución en segundo plano no está unido a su padre original y sigue ejecutándose en segundo plano:

$ exit

Inicie sesión nuevamente y mire la información del proceso:

$ ps -f 12571
UID        PID  PPID  C STIME TTY          TIME CMD
usr      12571     1  0 16:00 ?        00:00:00 thecommand
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.