¿Puedo nohup / screen un proceso ya iniciado?

260

Estoy haciendo algunas pruebas de secuencias de comandos de migración de datos de larga duración, a través de SSH. Digamos que empiezo a ejecutar un script alrededor de las 4 PM; ahora, llegan las 6 PM, y me estoy maldiciendo por no hacer todo esto screen.

¿Hay alguna forma de "retroactivamente" nohupun proceso, o necesito dejar mi computadora en línea toda la noche? Si no es posible adjuntar screena / nohupun proceso que ya he comenzado, ¿por qué? ¿Algo que ver con cómo interactúan los procesos padre / hijo? (No aceptaré una respuesta "no" que al menos no aborde la pregunta de "por qué" - lo siento;))

ojrac
fuente
44
Acabo de ver una publicación de blog interesante sobre disown. blogs.oracle.com/ksplice/entry/disown_zombie_children_and_the
ojrac

Respuestas:

212

Si estás usando Bash, puedes ejecutar disown -h job

desconocer

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

Sin opciones, cada especificación de trabajo se elimina de la tabla de trabajos activos. Si -hse da la opción, el trabajo no se elimina de la tabla, sino que se marca para que SIGHUP no se envíe al trabajo si el shell recibe un SIGHUP. Si jobspec no está presente, y no se proporciona la opción -ani -r, se utiliza el trabajo actual. Si no se proporciona una especificación de trabajo, la -a opción significa eliminar o marcar todos los trabajos; la -ropción sin un argumento jobspec restringe la operación a trabajos en ejecución.

gharper
fuente
Increíble; Esperaba que algo así apareciera.
ojrac
77
La vida puede ser injusta. gharper y yo publicamos esto aproximadamente al mismo tiempo :)
serverhorror
44
Eres mi héroe
Thomas Dignan
99
disown no es específico de bash. También está en zsh, ksh93, ...
Phil P
2
Descubrí que realmente debe usar disown %1si 1 es la especificación de trabajo, a diferencia de fg o bg, donde solo usa bg 1 serverwatch.com/tutorials/article.php/3935306/…
mltsy
81

Usar reptyr

Desde el archivo Léame:

reptyr - A tool for "re-ptying" programs.
-----------------------------------------

reptyr is a utility for taking an existing running program and
attaching it to a new terminal. Started a long-running process over
ssh, but have to leave and don't want to interrupt it? Just start a
screen, use reptyr to grab it, and then kill the ssh session and head
on home.

USAGE
-----

  reptyr PID

"reptyr PID" will grab the process with id PID and attach it to your
current terminal.

After attaching, the process will take input from and write output to
the new terminal, including ^C and ^Z. (Unfortunately, if you
background it, you will still have to run "bg" or "fg" in the old
terminal. This is likely impossible to fix in a reasonable way without
patching your shell.)

Algunas publicaciones de blog de su autor:

Jonathan Tran
fuente
Voy a seguir con las herramientas integradas (es decir, desconocer), pero no es tan flexible como reptyr. +1
ojrac
22

Para robar un proceso de un tty a su tty actual, puede probar este truco:

http://www.ucc.asn.au/~dagobah/things/grab.c

Necesita un reformateo para compilar las versiones actuales de Linux / glibc, pero aún funciona.

Juliano
fuente
1
Excepcionalmente genial.
ojrac
16

Cuando se inicia un proceso, STDIN, STDOUT y STDERR están conectados a algo . Generalmente no puede cambiar eso una vez que se inicia el comando. En el caso que está describiendo, probablemente sea un tty asociado con la sesión ssh. casi no hace más que ...

command < /dev/null > nohup.out 2>&1

Es decir, establece STDIN en / dev / null, STDOUT en un archivo y STDERR en STDOUT. Screen hace cosas mucho más sofisticadas que implican configurar ttys que se dirigen a sí mismos.

No conozco ninguna forma de retroceder o filtrar retroactivamente un proceso en ejecución. Si haces cd a / proc / $ pid / fd y ves a qué apuntan 0, 1 y 2.

Es posible que tenga suerte con Disown, pero no si el proceso intenta hacer algo con STDIN, STDOUT o STDERR.

freiheit
fuente
2
+1 por los buenos comentarios. st (din | out | err) es la otra mitad del problema, y ​​agradezco los consejos sobre dónde empezar a buscar, la próxima vez que esté en este atasco.
ojrac
66
De hecho, puedes cambiarlo en la mayoría de Unixes. Es un truco desagradable. Me encanta. :) Lo que debe hacer es conectarse al proceso utilizando el soporte de depuración como ptrace, luego forzar el proceso a llamar a dup2 () para volver a conectar 0,1,2 a otro controlador de archivos.
Zan Lynx
2
Sí, puedes cambiarlo. Implica pausar el proceso (SIGSTOP) y modificar los descriptores de archivo para fd 0, 1, 2. Luego reiniciar (SIGCONT).
Michael Martinez
13

Cryopid es un desarrollo adicional del autor de grab.c que congela un proceso en un archivo, que luego ejecuta (dentro de la pantalla) para reanudar el proceso.

TRS-80
fuente
1
¡Agradable! Traté de usar cryopid en la disertación de mi maestro sobre la migración de procesos, pero no funcionó todo el tiempo, sin importar lo que hice. Al final, tuve que usar dynckpt con una versión antigua de Linux. ¿Estás quizás involucrado en el desarrollo de la criopía? Veo que tu nombre es similar al dominio del autor.
Juliano
1
No estoy involucrado en el desarrollo, solo conozco al autor de la universidad. En este momento no tiene tiempo para mantener el criopsido, por lo que parece que algunas personas comenzaron a trabajar en él en sharesource.org/project/cryopid
TRS-80
12

Solo puedo darte un simple "No" sin el por qué de la parte de la pantalla, me interesaría la razón por ti mismo.

Sin embargo, ¿has probado disown(un bash incorporado)

~ $ echo $SHELL
/bin/bash
~ $ type disown
disown is a shell builtin
~ $ help disown
disown: disown [-h] [-ar] [jobspec ...]
     By default, removes each JOBSPEC argument from the table of active jobs.
    If the -h option is given, the job is not removed from the table, but is
    marked so that SIGHUP is not sent to the job if the shell receives a
    SIGHUP.  The -a option, when JOBSPEC is not supplied, means to remove all
    jobs from the job table; the -r option means to remove only running jobs.
servidorhorror
fuente
5

Hace poco vi un enlace a neercs , que es una utilidad similar a una pantalla creada con libcaca, una biblioteca de color ascii-art. Entre otras características, cuenta con la capacidad de tomar un proceso existente y volver a crearlo dentro de su sesión de neercs (pantalla).

Sin embargo, no lo he usado, así que no puedo comentar si funciona o no.

Daniel Lawson
fuente
2

Probablemente estoy subestimando esto, así que siéntete libre de corregirme (¡ya aprendí sobre disown!) ... ¿No funcionarían ctrl-Z y "bg" para al menos hacer que el proceso se ejecute en segundo plano? ¿O es el problema clave que aún querría ver STDOUT mientras se ejecuta?

Chris_K
fuente
1
Eso aún mataría el proceso cuando el propietario de tty muera, por lo que el OP debe dejar el cuadro donde inició el comando en ejecución, que es lo que quiere evitar
serverhorror
OK, lo compraré. Gracias por la explicación. Por lo tanto, las sugerencias
deshonestas
1
Todavía puede hacer esto, justo después de que tenga que negarlo -h: stackoverflow.com/a/625436/705198
AndrewPK el
2

Si puede vivir sin poder interactuar con el proceso y no se opone a cargar módulos aleatorios del núcleo, podría hacer algo peor que mirar a Snoop . Alternativamente, hay un par de otros proyectos. Aquí hay una llamada injcode, que en su mayoría puede hacer lo que desea hacer.

David Pashley
fuente
1

Quería usar nohup(o similar) para iniciar el linksnavegador de línea de comandos y adjuntarlo después de descargar un archivo del sitio web ASP.NET con un proceso de autenticación complicado y una gran cantidad de estados de vista ocultos que dificultaban el uso. con curl/ wget.

Finalmente terminé usando el tmuxque resolvió el trabajo simplemente genial:

  1. correr tmux
  2. Ejecute su aplicación ( linksen mi caso) y déjela ejecutándose
  3. Cerrar sesión SSH, la aplicación seguirá ejecutándose
  4. Conéctese con SSH a la misma máquina más tarde y ejecútelo tmux attachpara que la aplicación vuelva a la pantalla
Dmitry Gusev
fuente
tmux es genial, pero, como nohup o screen, solo funciona si lo usas antes de comenzar tu proceso. Esta pregunta es sobre los momentos en que te das cuenta de que necesitas tmux después de que tu proceso ya se esté ejecutando.
ojrac
-1

¿Es que te preocupa que la sesión se agote? En ese caso, podría Ctrl-z y bg el proceso, y luego simplemente poner algo para mantener viva la sesión como un "ping -t localhost" o "top".

Si es que desea cerrar sesión, me temo que no puedo agregar a los otros comentarios.

TrojanName
fuente
Es lo de cerrar sesión.
ojrac
1
Otra forma de evitar que se desconecte es ejecutar top. Eso siempre está barajando unos pocos bytes.
Rory el