ver segundo script procesos proceso plano ejecutar dejar corriendo cancelar shell nohup

shell - segundo - ¿Cómo pongo un proceso ya en ejecución en nohup?



ver procesos en linux (10)

  1. Ctrl + Z : esto detendrá el trabajo (¡no se cancelará!)
  2. bg - esto pondrá el trabajo en segundo plano y volverá al proceso en ejecución
  3. disown -a : esto cortará todos los archivos adjuntos con el trabajo (para que pueda cerrar el terminal y aún se ejecute)

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

No se colocará en nohup (según mi comprensión de su pregunta, no la necesita aquí).

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

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


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

Desde bash-manpage (man bash):

disown [-ar] [-h] [jobspec ...]

Sin opciones, cada especificación de trabajo se elimina de la tabla de trabajos activos. Si se da la opción -h, cada especificación de trabajo no se elimina de la tabla, pero se marca para que SIGHUP no se envíe al trabajo si el shell recibe un SIGHUP. Si no hay ninguna especificación de trabajo, y no se proporciona la opción -a ni la opción -r, se utiliza el trabajo actual. Si no se proporciona una 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 trabajo restringe la operación a trabajos en ejecución. El valor de retorno 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 hará nohup


En mi sistema AIX, lo intenté

nohup -p processid>

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


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

No puedes disown un pid o un proceso, no puedes disown 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 lanzar el trabajo en segundo plano (no suspenderlo) y luego rechazarlo.

Problema:

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

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


Esto me funcionó en Ubuntu Linux mientras estaba en tcshell.

  1. Ctrl Z para pausarlo

  2. bg para ejecutar en segundo plano

  3. jobs de jobs para obtener su número de trabajo

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


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

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

$./loop.sh

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

Ahora podemos cambiar a otro terminal (o presionar ^ Z y en el mismo terminal). Ahora gdb debe adjuntar a este proceso.

$ gdb -p <PID>

Esto detiene el script (si se está ejecutando). Su estado se puede verificar con ps -f <PID> , donde el campo STAT 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

Cerrar (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.

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 aplicar, pero /usr/sbin/lsof dice ''u'' para todos los manejadores de archivos std * (columna FD ), que es O_RDWR .

Verifiqué los valores en el archivo de cabecera /usr/include/bits/fcntl.h.

El archivo de salida podría abrirse con O_APPEND , como haría nohup , pero man open(2) no lo sugiere, debido a posibles problemas de NFS.

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

Ahora podemos comprobar el archivo recién redirigido. /usr/sbin/lsof -p <PID> imprime:

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(...) nuevamente usando un nombre de archivo diferente.

Ahora se debe lanzar el bash adjunto y podemos salir de gdb :

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

Si gdb detuvo la secuencia de comandos desde otra terminal, continuará 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 ponerlo en segundo plano. Así que presione ^Z

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

(Ahora estamos en el mismo estado que si se presionara ^Z 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 debe ejecutarse en segundo plano y desconectarse del terminal. El número en la salida del comando de jobs entre corchetes identifica el trabajo dentro de bash . Podemos usar en los siguientes comandos bash integrados 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 que nos llama. El proceso continúa ejecutándose en segundo plano. Si abandonamos 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

Las cosas gdb se pueden automatizar creando un archivo (por ejemplo, loop.gdb) que contiene los comandos y ejecutando 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 forro 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.


Lamentablemente, el rechazo es específico de bash y no está disponible en todos los shells.

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

nohup -p pid

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


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. Ejecute algo de SOMECOMMAND, digamos /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 interrumpa cuando el terminal se cierra.

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

Este proceso es el equivalente a ejecutar nohup SOMECOMMAND .


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

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.


Usando el control de trabajo 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 de trabajo] es el número de trabajo (como %1 para el primer trabajo en ejecución; busque su número con el comando de jobs ) para que el trabajo no finalice cuando se cierre el terminal.