¿Cuál es la diferencia entre nohup y ampersand?

243

Ambos nohup myprocess.out &o myprocess.out &configure myprocess.out para que se ejecute en segundo plano. Después de apagar la terminal, el proceso aún se está ejecutando. ¿Cual es la diferencia entre ellos?

Yarkee
fuente
¿Qué caparazón estás usando? el comportamiento varía según los shells
shx2
1
intento. Y sé por qué ahora según la respuesta de @nemo.
Yarkee
@Yarkee, si la respuesta se adapta a su problema, marque la pregunta como aceptada (la casilla de verificación debajo de los votos de la respuesta) para que no quede sin respuesta. Debería hacerlo para todas sus preguntas :)
nemo
1
shutdowndebe evitarse como un término con un significado específico de Linux., y ser reemplazado por exit.
Patrizio Bertoni

Respuestas:

317

nohupcapta la señal de colgar (ver man 7 signal) mientras que el ampersand no (excepto que el shell está configurado de esa manera o no se envía SIGHUP)

Normalmente, cuando se ejecuta un comando usando &y saliendo del shell después, el shell terminará el subcomando con la señal de suspensión ( kill -SIGHUP <pid>). Esto puede evitarse usando nohup, ya que capta la señal y la ignora para que nunca llegue a la aplicación real.

En caso de que esté usando bash, puede usar el comando shopt | grep huponpara averiguar si su shell envía SIGHUP a sus procesos secundarios o no. Si está desactivado, los procesos no finalizarán, ya que parece ser el caso para usted. Puede encontrar más información sobre cómo bash termina las aplicaciones aquí .

Hay casos en los nohupque no funciona, por ejemplo, cuando el proceso que inicia vuelve a conectar la SIGHUPseñal, como es el caso aquí .

nemo
fuente
Vale la pena señalar que solo &hace que el subcomando no reciba algunas señales (por ejemplo, SIGINT). nohupesencialmente se agrega SIGHUPa la lista de señales que no se propagan.
studgeek
46

myprocess.out &ejecutaría el proceso en segundo plano utilizando una subshell. Si el shell actual finaliza (por ejemplo, al cerrar sesión), todos los subconjuntos también finalizan, por lo que el proceso en segundo plano también finalizará. El comando nohup ignora la HUPseñal y, por lo tanto, incluso si el shell actual finaliza, el subshell myprocess.outcontinuará ejecutándose en segundo plano. Otra diferencia es que &solo no redirige el stdout / stderr, por lo que si hay alguna salida o error, estos se muestran en el terminal. nohup por otro lado redirige el stdout / stderr a nohup.outo $HOME/nohup.out.

amit_g
fuente
66
Corro myprocess.out &y salgo del caparazón. Sin embargo, cuando lo uso ps aux | grep myprocess.outen otro shell, todavía puedo encontrar "myprocess.out". Significa que el proceso aún se está ejecutando, no se terminará.
Yarkee
1
@amit_g Al matar el shell padre con kill -9no habrá un SIGHUP ya que esto requeriría que el shell padre maneje SIGKILL, que no puede.
nemo
2
Consultar tienda | grep hupon como se menciona en la otra respuesta.
amit_g
31

La mayoría de las veces iniciamos sesión en el servidor remoto usando ssh. Si inicia un script de shell y cierra la sesión, el proceso se cancela. Nohup ayuda a continuar ejecutando el script en segundo plano incluso después de cerrar sesión en el shell.

Nohup command name &
eg: nohup sh script.sh &

Nohup capta las señales HUP. Nohup no pone el trabajo automáticamente en segundo plano. Necesitamos decir que explícitamente usando &

Missgeorge
fuente
Gracias. No esperaba tu respuesta, pero el hecho de que esté aquí es genial. Responde a la pregunta que no hice: D
Vaibhav Kaushal
26

El uso de la y comercial (&) ejecutará el comando en un proceso secundario (secundario a la sesión bash actual). Sin embargo, cuando salga de la sesión, se eliminarán todos los procesos secundarios.

el uso de nohup + ampersand (&) hará lo mismo, excepto que cuando finalice la sesión, el padre del proceso secundario se cambiará a "1", que es el proceso "init", evitando así que el niño sea asesinado.

Michel
fuente
7

Corrígeme si me equivoco

  nohup myprocess.out &

nohup capta la señal de bloqueo, lo que significa que enviará un proceso cuando se cierre el terminal.

 myprocess.out &

El proceso puede ejecutarse pero se detendrá una vez que se cierre el terminal.

nohup myprocess.out

El proceso puede ejecutar incluso el terminal cerrado, pero puede detener el proceso presionando ctrl+ zen el terminal. Crt+ zno funciona si &existe.

John Joe
fuente
2

El comando nohup es una utilidad de enmascaramiento de señal y capta la señal de bloqueo. Donde como ampersand no capta las señales de colgar. El shell terminará el subcomando con la señal de colgar al ejecutar un comando usando & y saliendo del shell. Esto se puede evitar utilizando nohup, ya que capta la señal. El comando Nohup acepta la señal de colgar que puede ser enviada a un proceso por el núcleo y los bloquea. El comando Nohup es útil cuando un usuario desea iniciar una sesión de larga ejecución de la aplicación o cerrar la ventana en la que se inició el proceso. Cualquiera de estas acciones normalmente hace que el kernel cuelgue en la aplicación, pero un reiniciador de nohup permitirá que el proceso continúe. El uso del ampersand ejecutará el comando en un proceso hijo y este hijo de la sesión bash actual. Cuando salgas de la sesión, todos los procesos secundarios de ese proceso serán eliminados. El ampersand se relaciona con el control del trabajo para el shell activo. Esto es útil para ejecutar un proceso en una sesión en segundo plano.

santosh
fuente
0

Hay muchos casos en que pequeñas diferencias entre entornos pueden morderlo. Este es uno en el que me he encontrado recientemente. ¿Cuál es la diferencia entre estos dos comandos?

1 ~ $ nohup myprocess.out &
2 ~ $ myprocess.out &

La respuesta es la misma de siempre: depende.

nohup capta la señal de colgar mientras que el ampersand no.

¿Cuál es la señal de colgar?

SIGHUP: bloqueo detectado en el terminal de control o muerte del proceso de control (valor: 1).

Normalmente, cuando ejecuta un comando usando & y luego sale del shell, el shell terminará el subcomando con la señal de suspensión (como kill -SIGHUP $ PID). Esto se puede evitar usando nohup, ya que capta la señal y la ignora para que nunca llegue a la aplicación real.

Bien, pero como en este caso siempre hay 'peros'. No hay diferencia entre estos métodos de inicio cuando el shell se configura de manera que no envía SIGHUP en absoluto.

En caso de que esté usando bash, puede usar el comando especificado a continuación para averiguar si su shell envía SIGHUP a sus procesos secundarios o no:

~ $ shopt | grep hupon

Y además, hay casos en los que nohup no funciona. Por ejemplo, cuando el proceso que inicia vuelve a conectar la señal NOHUP (se realiza en el interior, en el nivel del código de la aplicación).

En el caso descrito, la falta de diferencias me mordió cuando dentro de un script de inicio de servicio personalizado hubo una llamada a un segundo script que configura e inicia la aplicación adecuada sin un comando nohup.

En un entorno Linux, todo funcionó sin problemas, en un segundo la aplicación se cerró tan pronto como salió el segundo script (detectar ese caso, por supuesto, me llevó mucho más tiempo de lo que podrías pensar: stuck_out_tongue :).

Después de agregar nohup como método de inicio a la segunda secuencia de comandos, la aplicación sigue ejecutándose incluso si las secuencias de comandos se cierran y este comportamiento se volvió coherente en ambos entornos.

Devender Goyal
fuente