Pregunta ¿Cómo pongo un proceso que ya se está ejecutando bajo nohup?


Tengo un proceso que ya se está ejecutando durante mucho tiempo y no quiero terminarlo.

¿Cómo lo pongo en nohup (es decir, cómo hago que continúe funcionando incluso si cierro el terminal?)


775
2018-03-09 08:33


origen


Respuestas:


Utilizando el Control de trabajo de bash para enviar el proceso a un segundo plano:

  1. Ctrl+Z detener (pausar) el programa y volver al shell.
  2. bg para ejecutarlo en el fondo.
  3. disown -h [job-spec] donde [job-spec] es el número de trabajo (como %1 para el primer trabajo en ejecución; encuentre su número con el jobs comando) para que el trabajo no se elimine cuando se cierra el terminal.

1153
2018-03-09 08:41



Supongamos por alguna razón Ctrl+Z tampoco funciona, vaya a otra terminal, encuentre la identificación del proceso (usando ps) y correr:

kill -20 PID 
kill -18 PID

kill -20 (SIGTSTP) suspenderá el proceso y kill -18 (SIGCONT) reanudará el proceso, en segundo plano. Entonces, cerrar ambos terminales no detendrá su proceso.


141
2018-04-23 08:01



El comando para separar un trabajo en ejecución del shell (= lo hace nohup) es disown y un comando de shell básico.

De bash-manpage (hombre bash):

repudiar [-ar] [-h] [especificación de trabajos ...]

Sin opciones, cada espec de trabajos se elimina de la tabla de trabajos activos. Si se da la opción -h, cada especificación de trabajo no es   eliminado de la tabla, pero está marcado para que SIGHUP no se envíe al trabajo si el shell recibe un SIGHUP. Si no hay trabajospec   presente, y no se suministran las opciones -a, ni -r, se utiliza el trabajo actual. Si no se proporciona ninguna especificación de trabajo, la opción -a   significa eliminar o marcar todos los trabajos; la opción -r sin un argumento de especificación de trabajos restringe la operación a trabajos en ejecución. El regreso   el valor es 0 a menos que una especificación de trabajos no especifique un trabajo válido.

Eso significa que un simple

disown -a

eliminará todos los trabajos de la tabla de trabajo y los hará nohup


72
2018-03-09 08:38



Estas son buenas respuestas anteriores, solo quería agregar una aclaración:

No puedes disown un pid o proceso, tú disown un trabajo, y esa es una distinción importante.

Un trabajo es algo que es una noción de un proceso que está adjunto a un caparazón, por lo tanto, tiene que tirar el trabajo a un segundo plano (no suspenderlo) y luego repudiarlo.

Problema:

%  jobs
[1]  running java 
[2]  suspended vi
%  disown %1

Ver http://www.quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/jobcontrol/ para una discusión más detallada de Unix Job Control.


60
2017-11-19 15:48



Desafortunadamente disown es específico de bash y no está disponible en todos los shells.

Algunos sabores de Unix (por ejemplo, AIX y Solaris) tienen una opción en nohup comando mismo que se puede aplicar a un proceso en ejecución:

nohup -p pid

Ver http://en.wikipedia.org/wiki/Nohup


36
2018-03-16 23:49



La respuesta de Node es realmente genial, pero deja abierta la pregunta de cómo pueden redireccionar stdout y stderr. Encontré una solución en Unix y Linux, pero tampoco es completo. Me gustaría fusionar estas dos soluciones. Aquí está:

Para mi prueba hice un pequeño script bash llamado loop.sh, que imprime el pid de sí mismo con un minuto de sueño en un ciclo infinito.

$./loop.sh

Ahora obtenga el PID de este proceso de alguna manera. Generalmente ps -C loop.sh es lo suficientemente bueno, pero está impreso en mi caso.

Ahora podemos cambiar a otro terminal (o presionar ^ Z y en el mismo terminal). Ahora gdb debería estar unido a este proceso.

$ gdb -p <PID>

Esto detiene la secuencia de comandos (si se está ejecutando). Su estado puede ser verificado por ps -f <PID>, donde el STAT el campo es 'T +' (o en el caso de ^ Z 'T'), que significa (hombre ps (1))

    T Stopped, either by a job control signal or because it is being traced
    + is in the foreground process group

(gdb) call close(1)
$1 = 0

Cerrar (1) devuelve cero en caso de éxito.

(gdb) call open("loop.out", 01102, 0600)
$6 = 1

Abrir (1) devuelve el nuevo descriptor de archivo si tiene éxito.

Este abierto es igual a open(path, O_TRUNC|O_CREAT|O_RDWR, S_IRUSR|S_IWUSR). En lugar de O_RDWR  O_WRONLY podría ser aplicado, pero /usr/sbin/lsof dice 'u' para todos los manejadores de archivos std * (FD columna), que es O_RDWR.

Comprobé los valores en /usr/include/bits/fcntl.h archivo de encabezado.

El archivo de salida se puede abrir con O_APPEND, como nohup haría, pero esto no es sugerido por man open(2), debido a posibles problemas de NFS.

Si obtenemos -1 como valor de retorno, entonces call perror("") imprime el mensaje de error Si necesitamos el error, use p errno gdb comand.

Ahora podemos verificar el archivo nuevamente redirigido. /usr/sbin/lsof -p <PID> huellas dactilares:

loop.sh <PID> truey    1u   REG   0,26        0 15008411 /home/truey/loop.out

Si queremos, podemos redireccionar stderr a otro archivo, si queremos usar call close(2) y call open(...) de nuevo usando un nombre de archivo diferente.

Ahora el adjunto bash tiene que ser lanzado y podemos dejarlo gdb:

(gdb) detach
Detaching from program: /bin/bash, process <PID>
(gdb) q

Si el script fue detenido por gdb desde otra terminal continúa funcionando. Podemos volver a la terminal de loop.sh. Ahora no escribe nada en la pantalla, sino que ejecuta y escribe en el archivo. Tenemos que ponerlo en segundo plano. Así que presione ^Z.

^Z
[1]+  Stopped                 ./loop.sh

(Ahora estamos en el mismo estado que si ^Z fue presionado al principio.)

Ahora podemos verificar el estado del trabajo:

$ ps -f 24522
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
<UID>    <PID><PPID>  0 11:16 pts/36   S      0:00 /bin/bash ./loop.sh
$ jobs
[1]+  Stopped                 ./loop.sh

Por lo tanto, el proceso debería ejecutarse en segundo plano y desconectarse de la terminal. El número en el jobs salida del comando entre corchetes identifica el trabajo dentro bash. Podemos usar en el siguiente construido en bash comandos que aplican un signo '%' antes del número de trabajo:

$ bg %1
[1]+ ./loop.sh &
$ disown -h %1
$ ps -f <PID>
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
<UID>    <PID><PPID>  0 11:16 pts/36   S      0:00 /bin/bash ./loop.sh

Y ahora podemos abandonar el llamado bash. El proceso continúa ejecutándose en segundo plano. Si dejamos su PPID se convierte en 1 (proceso init (1)) y la terminal de control se vuelve desconocida.

$ ps -f <PID>
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
<UID>    <PID>     1  0 11:16 ?        S      0:00 /bin/bash ./loop.sh
$ /usr/bin/lsof -p <PID>
...
loop.sh <PID> truey    0u   CHR 136,36                38 /dev/pts/36 (deleted)
loop.sh <PID> truey    1u   REG   0,26     1127 15008411 /home/truey/loop.out
loop.sh <PID> truey    2u   CHR 136,36                38 /dev/pts/36 (deleted)

COMENTARIO

El material de gdb se puede automatizar creando un archivo (por ejemplo, loop.gdb) que contiene los comandos y ejecuta gdb -q -x loop.gdb -p <PID>. Mi loop.gdb se ve así:

call close(1)
call open("loop.out", 01102, 0600)
# call close(2)
# call open("loop.err", 01102, 0600)
detach
quit

O uno puede usar el siguiente trazador de líneas en su lugar:

gdb -q -ex 'call close(1)' -ex 'call open("loop.out", 01102, 0600)' -ex detach -ex quit -p <PID>

Espero que esta sea una descripción bastante completa de la solución.


21
2017-10-10 09:35



Para enviar el proceso en ejecución a nohup (http://en.wikipedia.org/wiki/Nohup)

nohup -p pid no funcionó para mí

Luego probé los siguientes comandos y funcionó muy bien

  1. Ejecuta algo de SOMECOMMAND, decir /usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1.

  2. Ctrl+Z detener (pausar) el programa y volver al shell.

  3. bg para ejecutarlo en el fondo.

  4. disown -h para que el proceso no se mate cuando se cierra el terminal.

  5. Tipo exit para salir del caparazón porque ahora está listo para ir ya que la operación se ejecutará en segundo plano en su propio proceso, por lo que no está vinculada a un caparazón.

Este proceso es el equivalente a correr nohup SOMECOMMAND.


6
2017-09-27 06:48



En mi sistema AIX, probé

nohup -p  processid>

Esto funcionó bien. Continuó ejecutando mi proceso incluso después de cerrar las ventanas de la terminal. Tenemos ksh como shell por defecto para que el bg y disown los comandos no funcionaron


1
2018-03-03 16:16



  1. ctrl + z  - Esto pausará el trabajo (¡no va a cancelar!)
  2. bg - Esto pondrá el trabajo en segundo plano y regresará en proceso
  3. disown -a - Esto cortará todos los archivos adjuntos con el trabajo (para que pueda cerrar el terminal y seguirá ejecutándose)

Estos sencillos pasos le permitirán cerrar la terminal mientras se mantiene el proceso en ejecución.

No se pondrá nohup (basado en mi comprensión de tu pregunta, no la necesitas aquí).


1
2018-03-24 17:06



Esto funcionó para mí en Ubuntu Linux mientras estaba en tcshell.

  1. CtrlZ pausarlo

  2. bg para ejecutar en segundo plano

  3. jobs para obtener su número de trabajo

  4. nohup %n donde n es el número de trabajo


0
2017-08-04 22:57