2008-11-12 18 views
262

Estoy trabajando en una máquina Linux a través de SSH (Putty). Necesito dejar un proceso ejecutándose durante la noche, así que pensé que podría hacer eso comenzando el proceso en segundo plano (con un símbolo comercial al final del comando) y redirigiendo la salida estándar a un archivo. Para mi sorpresa, eso no funciona. Tan pronto como cierro la ventana de Putty, el proceso se detiene.Linux: Impedir que se detenga un proceso en segundo plano después de cerrar el cliente SSH

¿Cómo puedo evitar que esto suceda?

Respuesta

281

Consulte el programa "nohup".

+4

¿Cómo se detiene después? –

+9

Inicie sesión y haga "matar ". Use "pidof" si no conoce el pid. – JesperE

+26

Puede usar 'nohup command>/dev/null 2> & 1 &' para ejecutar en segundo plano sin crear ninguna salida stdout o stderr (no 'nohup.out' file) – KCD

157

Recomendaría usar GNU Screen. Le permite desconectarse del servidor mientras todos sus procesos continúan ejecutándose. No sé cómo viví sin eso antes de saber que existía.

+7

Este es uno de los mejores software que he usado. Seriamente. Lo tengo funcionando en un recuadro de BSD al que ingreso desde TODAS PARTES, y simplemente puedo reacoplarlo a mi pantalla y tener todos mis terminales donde hago todo tipo de cosas. –

+1

Puedo dar fe de esto. La pantalla es una gran aplicación. La capacidad de volver a conectar es increíble y ahorra mucho trabajo potencialmente perdido. – willasaywhat

+0

Incluso lo uso en máquinas locales y anexo múltiples xterms a la misma sesión de pantalla (pantalla -x). De esa manera puedo abrir muchas ventanas dentro de mi sesión de pantalla, y cambiar libremente mis varios xterms de ventana a ventana. La pantalla –

75

Cuando la sesión se cierra, el proceso recibe la señal SIGHUP que aparentemente no capta. Puede utilizar el comando nohup al poner en marcha el proceso o la fiesta de comando integrado disown -h después de comenzar el proceso para evitar que esto suceda:

> 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. 
+2

La ventaja aquí es que el rechazo funciona para procesos que ya se han iniciado. –

+0

¿'jobspec' significa el pid? – Stewart

+0

No se preocupe, encuentre esta respuesta aquí http://stackoverflow.com/questions/625409/how-do-i-put-an-already-running-process-under-nohup – Stewart

33
nohup blah & 

sustituir el nombre de proceso para bla!

+0

es posible que desee agregar redireccionamiento estándar y estándar error. –

+7

nohup redirecciona stdout y stderr a nohup.out (o nohup.out y nohup.err dependiendo de la versión), por lo tanto, a menos que ejecute varios comandos, no es necesario. –

5

Nohup permite que un proceso de cliente no se mate si se mata el proceso principal, como argumento cuando finaliza la sesión. Incluso mejor todavía utilizan:

nohup /bin/sh -c "echo \$\$ > $pidfile; exec $FOO_BIN $FOO_CONFIG " > /dev/null 

nohup hace que el proceso se inicia inmune a la terminación que su sesión de SSH con los procesos hijos son matar a usted salir de la sesión. El comando que di le proporciona una forma de almacenar el pid de la aplicación en un archivo pid para que pueda eliminarlo posteriormente y permita que el proceso se ejecute después de que se haya desconectado.

11

Como otros han notado, para ejecutar un proceso en segundo plano y desconectarse de su sesión SSH, necesita que el proceso en segundo plano se desasocie apropiadamente de su terminal de control, que es el pseudo-tty que el SSH usos de sesión.

Puede encontrar información sobre procesos de demonización en libros como "Advanced Network Program, Vol 1, 3rd Edn" de Stevens o "Advanced Unix Programming" de Rochkind.

Recientemente (en los últimos años) tuve que lidiar con un programa recalcitrante que no se demonizó adecuadamente. Terminé lidiando con eso al crear un programa genérico de demonización, similar a nohup pero con más controles disponibles.

Usage: daemonize [-abchptxV][-d dir][-e err][-i in][-o out][-s sigs][-k fds][-m umask] -- command [args...] 
    -V   print version and exit 
    -a   output files in append mode (O_APPEND) 
    -b   both output and error go to output file 
    -c   create output files (O_CREAT) 
    -d dir  change to given directory 
    -e file  error file (standard error - /dev/null) 
    -h   print help and exit 
    -i file  input file (standard input - /dev/null) 
    -k fd-list keep file descriptors listed open 
    -m umask set umask (octal) 
    -o file  output file (standard output - /dev/null) 
    -s sig-list ignore signal numbers 
    -t   truncate output files (O_TRUNC) 
    -p   print daemon PID on original stdout 
    -x   output files must be new (O_EXCL) 

El doble-tablero es opcional en los sistemas que no utilizan la función GNU getopt(); es necesario (o debe especificar POSIXLY_CORRECT en el entorno) en Linux, etc. Dado que el doble tablero funciona en todas partes, lo mejor es usarlo.

Todavía puede contactarme (nombre apellido dot en gmail punto com) si quiere la fuente daemonize.

Sin embargo, el código es ahora (por fin) disponible en GitHub en mis SOQ (Stack Overflow Preguntas) repositorio como archivo daemonize-1.10.tgz en el subdirectorio packages .

+13

¿Por qué no pones la fuente en github o bitbucket? – Rob

+5

¿Por qué la ausencia de la fuente de github justifica un voto a la baja? –

+4

@JonathanLeffler En mi humilde opinión, enumerar todas las opciones geniales de un programa que no está disponible al público de ninguna forma (ni siquiera comercialmente) bordea el tiempo del lector. – DepressedDaniel

4

Si usa la pantalla para ejecutar un proceso como root, tenga cuidado con la posibilidad de ataques de elevación de privilegios. Si su propia cuenta se ve comprometida de alguna manera, habrá una forma directa de hacerse cargo de todo el servidor.

Si este proceso necesita ejecutarse regularmente y tiene suficiente acceso en el servidor, una mejor opción sería usar cron para ejecutar el trabajo. También puede usar init.d (el súper daemon) para comenzar su proceso en segundo plano, y puede terminar tan pronto como se haya completado.

16

Personalmente, me gusta el comando 'lote'.

$ batch 
> mycommand -x arg1 -y arg2 -z arg3 
> ^D 

Esto lo incluye en segundo plano, y luego le envía los resultados por correo. Es una parte de cron.

1

Si está dispuesto a ejecutar también aplicaciones X, use xpra junto con "pantalla".

32

daemonize? nohup? ¿PANTALLA? (tmux ftw, la pantalla es basura ;-)

Simplemente haz lo que todas las demás aplicaciones han hecho desde el principio: doble tenedor.

# ((exec sleep 30)&) 
# grep PPid /proc/`pgrep sleep`/status 
PPid: 1 
# jobs 
# disown 
bash: disown: current: no such job 

Bang! Hecho :-) Lo he usado innumerables veces en todo tipo de aplicaciones y en muchas máquinas antiguas. Puede combinar con redirecciones y otras cosas para abrir un canal privado entre usted y el proceso.

Cree coproc.sh:

#!/bin/bash 

IFS= 

run_in_coproc() { 
    echo "coproc[$1] -> main" 
    read -r; echo $REPLY 
} 

# dynamic-coprocess-generator. nice. 
_coproc() { 
    local i o e n=${1//[^A-Za-z0-9_]}; shift 
    exec {i}<> <(:) {o}<> >(:) {e}<> >(:) 
. /dev/stdin <<COPROC "${@}" 
    (("\[email protected]")&) <&$i >&$o 2>&$e 
    $n=($o $i $e) 
COPROC 
} 

# pi-rads-of-awesome? 
for x in {0..5}; do 
    _coproc COPROC$x run_in_coproc $x 
    declare -p COPROC$x 
done 

for x in COPROC{0..5}; do 
. /dev/stdin <<RUN 
    read -r -u \${$x[0]}; echo \$REPLY 
    echo "$x <- main" >&\${$x[1]} 
    read -r -u \${$x[0]}; echo \$REPLY 
RUN 
done 

y luego

# ./coproc.sh 
declare -a COPROC0='([0]="21" [1]="16" [2]="23")' 
declare -a COPROC1='([0]="24" [1]="19" [2]="26")' 
declare -a COPROC2='([0]="27" [1]="22" [2]="29")' 
declare -a COPROC3='([0]="30" [1]="25" [2]="32")' 
declare -a COPROC4='([0]="33" [1]="28" [2]="35")' 
declare -a COPROC5='([0]="36" [1]="31" [2]="38")' 
coproc[0] -> main 
COPROC0 <- main 
coproc[1] -> main 
COPROC1 <- main 
coproc[2] -> main 
COPROC2 <- main 
coproc[3] -> main 
COPROC3 <- main 
coproc[4] -> main 
COPROC4 <- main 
coproc[5] -> main 
COPROC5 <- main 

Y hay que ir, lo desovar. el < (:) abre una tubería anónima a través de la sustitución del proceso, que muere, pero la tubería se queda porque tiene un control. Yo suelo hacer un sleep 1 en lugar de : debido a su poco picante, y me gustaría obtener un "archivo de ocupado" error - no ocurre si se corrió un comando real (por ejemplo, command true)

"heredoc abastecimiento":

. /dev/stdin <<EOF 
[...] 
EOF 

Esto funciona en todos y cada uno de los shell que he probado, incluyendo busybox/etc (initramfs). Nunca lo había visto antes, lo descubrí independientemente mientras insistía, ¿quién sabía que la fuente podía aceptar args? Pero a menudo sirve como una forma mucho más manejable de evaluación, si existe tal cosa.

+2

por qué el voto abajo ... ¿y qué pasa si la pregunta es vieja; es obviamente relevante considerando que hay otras 11 respuestas que apestan. esta solución es, sin el sistema, la forma idiomática y aceptada para demonizar durante los últimos 30 años, aplicaciones no sin sentido, por ejemplo. nohup et al. – anthonyrisinger

+5

no importa qué tan buena sea su respuesta, a veces a alguien en SO no le gustará y rechazará. Es mejor no preocuparse demasiado por eso. –

+0

Esta técnica no funciona cuando se intenta iniciar un trabajo mediante programación mediante ssh, p. Ej. '$ ssh myhost' ((exec sleep 30) &) "' – tbc0

2

yo también iría para el programa de la pantalla (Sé que some1 respuesta más estaba pantalla, pero esta es una terminación)

no sólo el hecho de que &, ctrl + z bg disown, nohup, etc.puede darte una desagradable sorpresa de que cuando cierres sesión el trabajo todavía se mate (no sé por qué, pero me pasó a mí, y no me molestó porque cambié para usar la pantalla, pero supongo que la solución anthonyrisinger es doble bifurcan resolvería eso), también de pantalla tienen una importante ventaja sobre que acaba de regresar a tierra:

screen will background your process without losing interactive control to it 

y por cierto, esta es una pregunta que nunca le pediría en primer lugar :) ... i pantalla de uso desde el principio de hacer cualquier cosa en cualquier unix ... yo (casi) NUNCA trabajo en un shell de Unix/Linux sin iniciar la pantalla primero ... y debería parar ahora, o comenzaré una presentación interminable de lo que es una buena pantalla y qué puede hacer por ti ... búscalo tú solo, vale la pena;)

+0

PS anthonyrisinger, eres bueno, te lo aseguro pero ... ¿30 años? apuesto a que es una solución cuando &, bg, nohup o pantalla aún no estaban allí, y sin ofender, aprecio tu conocimiento, pero eso es demasiado complicado para usarlo :) – THESorcerer

+1

[(aparte: ** ver Tmux **)] (http://tmux.sourceforge.net/) aunque esto me precede (1987), '&' (ejecución asincrónica) fue introducido por [el shell Thompson en 1971] (http://en.wikipedia.org/wiki)/Thompson_shell), para la ** primera ** versión de UNIX ... [así que literalmente "siempre ha sido"] (http://v6shell.org/man/osh.1.html) ;-) ¡ay! era demasiado conservador, en realidad han pasado 41 años. – anthonyrisinger

2

También está el comando daemon del paquete libslack de código abierto.

daemon es bastante configurable y se preocupa por todas las cosas tediosas del daemon como el reinicio automático, el registro o el manejo de archivos pidfile.

2

Anexar esta cadena para su comando:> & - 2> & - < & - &. > & - significa cierre estándar. 2> & - significa cerrar stderr. < & - significa cerrar stdin. & significa ejecutar en segundo plano. Esto funciona para comenzar un trabajo mediante programación a través de SSH, también:

$ ssh myhost 'sleep 30 >&- 2>&- <&- &' 
# ssh returns right away, and your sleep job is running remotely 
$ 
4

nohup es muy bueno si desea registrar sus datos en un archivo. Pero cuando pasa al segundo plano, no puedes darle una contraseña si tus scripts lo piden. Creo que debes probar screen. es una utilidad que puedes instalar en tu distribución de Linux usando yum por ejemplo en CentOS yum install screen y luego acceder a tu servidor a través de masilla u otro software, en tu tipo de shell screen. Abrirá la pantalla [0] en masilla. Haz tu trabajo. Puede crear más pantalla [1], pantalla [2], etc. en la misma sesión de masilla. Comandos

básico que necesita saber:

Para iniciar la pantalla

pantalla


Para c reate siguiente pantalla

ctrl + a + c


Para pasar a n pantalla ext ha creado

ctrl + a + n


Para d Etach

ctrl + a + d


Durante el trabajo, cierre su masilla.Y la próxima vez que se conecte a través de al tipo de masilla

pantalla -r

Para volver a conectar a la pantalla, y se puede ver el proceso todavía se ejecuta en pantalla. Y para salir de la pantalla escriba #exit.

Para obtener más información, consulte man screen.

+0

suponiendo que 'yum' es la herramienta correcta, cuando no se conoce la distribución, no es bueno. debe dejar en claro en qué 'pantalla' de las distribuciones se puede instalar con 'yum'. – tymik

+0

Gracias @tymik he editado mi respuesta original. –

4

En un sistema basado en Debian (en la máquina remota) Instalar:

sudo apt-get install tmux

Uso:

tmux

ejecute los comandos que desee

Para cambiar el nombre de sesión:

Ctrl + B continuación $

conjunto Nombre

Para salir de la sesión:

Ctrl + B continuación D

(esto deja la sesión tmux). Luego, puedes desconectarte de SSH.

Cuando tenga que volver/comprobar de nuevo, la puesta en marcha de SSH, y entrar

tmux adjuntar session_name

Se le llevará de nuevo a la sesión tmux.

2

Para la mayoría de los procesos se puede pseudo-daemonize que utilizan este viejo truco de Linux de línea de comandos:

# ((mycommand &)&) 

Por ejemplo:

# ((sleep 30 &)&) 
# exit 

A continuación, inicie una nueva ventana de terminal y:

# ps aux | grep sleep 

Se mostrará que sleep 30 aún se está ejecutando.

Lo que ha hecho es iniciar el proceso como hijo de un niño, y cuando sale, el comando nohup que normalmente desencadenaría el proceso para salir no cae en cascada al nieto, dejándolo como un proceso huérfano, aún en ejecución.

Prefiero este enfoque de "configúrelo y olvídese", sin necesidad de ocuparse de nohup, screen, tmux, redirección de E/S ni nada de eso.

1

La respuesta aceptada sugiere el uso de nohup. Prefiero sugerir usar pm2. El uso de pm2 sobre nohup tiene muchas ventajas, como mantener la aplicación viva, mantener los archivos de registro para la aplicación y mucho más otras características. Para más detalles check this out.

Para instalar PM2 es necesario descargar NPM. Para el sistema basado en Debian

sudo apt-get install npm 

y para Redhat

sudo yum install npm 

O usted puede seguir these instruction. Después de instalar NPM usarlo para instalar PM2

npm install [email protected] -g 

Una vez que su hecho se puede iniciar la aplicación por

$ pm2 start app.js    # Start, Daemonize and auto-restart application (Node) 
$ pm2 start app.py    # Start, Daemonize and auto-restart application (Python) 

Para el control de procesos de uso de comandos siguientes:

$ pm2 list      # List all processes started with PM2 
$ pm2 monit      # Display memory and cpu usage of each app 
$ pm2 show [app-name]   # Show all informations about application 

Administre procesos utilizando el nombre de la aplicación o la identificación del proceso o administre todos los procesos ses juntos:

$ pm2 stop  <app_name|id|'all'|json_conf> 
$ pm2 restart <app_name|id|'all'|json_conf> 
$ pm2 delete <app_name|id|'all'|json_conf> 

archivos de registro se pueden encontrar en

$HOME/.pm2/logs #contain all applications logs 

archivos ejecutables binarios también se pueden ejecutar con PM2. Tienes que hacer un cambio en el archivo jason. Cambie el "exec_interpreter" : "node", al "exec_interpreter" : "none". (consulte el attributes section).

#include <stdio.h> 
#include <unistd.h> //No standard C library 
int main(void) 
{ 
    printf("Hello World\n"); 
    sleep (100); 
    printf("Hello World\n"); 

    return 0; 
} 

Compilar código anterior

gcc -o hello hello.c 

y ejecutarlo con np2 en el fondo

pm2 start ./hello 
+0

¿Se puede utilizar esto para ejecutar ejecutables binarios? – GetFree

+0

@GetFree; Sí. Usted puede. – haccks

+0

Agregue un ejemplo por favor. La respuesta como está ahora parece que solo es buena para los archivos de script. – GetFree

0

En systemd/Linux, systemd-run es una buena herramienta para poner en marcha procesos de sesión independiente. Los enemigos odiarán

Cuestiones relacionadas