Pregunta

Tengo un proceso que ya lleva mucho tiempo ejecutándose y no quiero finalizarlo.

¿Cómo lo pongo en nohup (es decir, cómo hago para que continúe ejecutándose incluso si cierro la terminal?)

¿Fue útil?

Solución

Uso del Control de trabajos de bash para enviar el proceso al fondo:

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

Otros consejos

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

kill -SIGSTOP PID 
kill -SIGCONT PID

SIGSTOP suspenderá el proceso y SIGCONT reanudará el proceso, en segundo plano. Entonces, cerrar ambos terminales no detendrá su proceso.

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

Desde bash-manpage (man bash):

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

Sin opciones, cada especificación de trabajo se elimina de la tabla de trabajos activos.Si se da la opción -h, cada JobSpec no se elimina de la tabla, sino que se marca para que el suspiro no se envíe al trabajo si el shell recibe un suspiro.Si no se especifica ningún jobspec presente, y no se proporciona ni la opción -a ni la opción -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 puestos de trabajo;la opción -r sin un argumento de especificación de trabajo restringe la operación a trabajos en ejecución.El regreso value es 0 a menos que una especificación de trabajo no especifique un trabajo válido.

Eso significa que un simple

disown -a

eliminará todos los trabajos de la tabla de trabajos y los desactivará

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

No puede disown un pid o proceso, usted <=> un trabajo, y esa es una distinción importante.

Un trabajo es algo que es una noción de un proceso que se adjunta a un shell, por lo tanto, debe arrojar el trabajo en segundo plano (no suspenderlo) y luego rechazarlo.

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.

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

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

nohup -p pid

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

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

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

$./loop.sh

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

Ahora podemos cambiar a otra terminal (o presionar ^Z y en la misma terminal).Ahora gdb debe adjuntarse a este proceso.

$ gdb -p <PID>

Esto detiene el script (si se está ejecutando).Su estado puede comprobarse mediante ps -f <PID>, donde el STAT El campo es 'T+' (o en el caso de ^Z 'T'), lo que significa (man 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

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

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

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

Esta apertura es igual a open(path, O_TRUNC|O_CREAT|O_RDWR, S_IRUSR|S_IWUSR).En lugar de O_RDWR O_WRONLY podría aplicarse, pero /usr/sbin/lsof dice 'u' para todos los controladores de archivos estándar* (FD columna), que es O_RDWR.

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

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 errno, use p errno Comando gdb.

Ahora podemos comprobar el archivo recién 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 redirigir stderr a otro archivo, si queremos usar call close(2) y call open(...) nuevamente usando un nombre de archivo diferente.

Ahora el adjunto bash tiene que ser liberado y podemos salir gdb:

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

Si el guión fue detenido por gdb desde otro terminal continúa ejecutándose.Podemos volver a la terminal de loop.sh.Ahora no escribe nada en la pantalla, sino que se ejecuta y escribe en el archivo.Tenemos que dejarlo en un segundo plano.Así que presiona ^Z.

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

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

Ahora podemos comprobar 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 del terminal.El número en el jobs La salida del comando entre corchetes identifica el trabajo dentro. bash.Podemos usar en el siguiente incorporado 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 salir de la fiesta de llamadas.El proceso continúa ejecutándose en segundo plano.Si salimos, su PPID se convierte en 1 (proceso init(1)) y el terminal de control se vuelve desconocido.

$ 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 (p. ej.loop.gdb) que contiene los comandos y ejecutar 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 se puede utilizar el siguiente delineador 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.

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 SOMECOMMAND, diga /usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1.

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

  3. bg para ejecutarlo en segundo plano.

  4. disown -h para que el proceso no se cancele cuando el terminal se cierre.

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

Este proceso es el equivalente a ejecutar nohup SOMECOMMAND.

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 predeterminado, por lo que bg y disown Los comandos no funcionaron.

  1. ctrl + z : esto pausará el trabajo (¡no se cancelará!)
  2. bg - esto pondrá el trabajo en segundo plano y volverá al proceso de ejecución
  3. disown -a - esto cortará todos los archivos adjuntos con el trabajo (por lo que puede cerrar el terminal y aún se ejecutará)

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

No se colocará en nohup (según tengo entendido su pregunta, no la necesita aquí).

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

  1. Ctrl Z para 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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top