Primero veamos qué sucede si un programa se inicia desde un shell interactivo (conectado a una terminal) sin &
(y sin ninguna redirección). Así que supongamos que acabas de escribir foo
:
- Se
foo
crea el proceso en ejecución .
- El proceso hereda stdin, stdout y stderr del shell. Por lo tanto, también está conectado al mismo terminal.
- Si el shell recibe un
SIGHUP
, también envía un SIGHUP
al proceso (que normalmente hace que el proceso finalice).
- De lo contrario, el shell espera (se bloquea) hasta que finaliza el proceso.
Ahora, veamos qué sucede si pones el proceso en segundo plano, es decir, escribe foo &
:
- Se
foo
crea el proceso en ejecución .
- El proceso hereda stdout / stderr del shell (por lo que aún escribe en el terminal).
- El proceso en principio también hereda stdin, pero tan pronto como intenta leer desde stdin, se detiene.
- Se incluye en la lista de trabajos en segundo plano que gestiona el shell, lo que significa especialmente:
- Está en la lista
jobs
y se puede acceder usando %n
(donde n
está el número de trabajo).
- Se puede convertir en un trabajo en primer plano utilizando
fg
, en cuyo caso continúa como si no lo hubiera utilizado &
(y si se detuvo debido a intentar leer desde la entrada estándar, ahora puede proceder a leer desde el terminal).
- Si el shell recibió un
SIGHUP
, también envía un SIGHUP
al proceso. Dependiendo del shell y posiblemente de las opciones establecidas para el shell, al terminar el shell también enviará un mensaje SIGHUP
al proceso.
Ahora disown
elimina el trabajo de la lista de trabajos del shell, por lo que todos los subpuntos anteriores ya no se aplican (incluido el proceso enviado SIGHUP
por el shell). Sin embargo, tenga en cuenta que todavía está conectado al terminal, por lo que si el terminal se destruye (lo que puede suceder si fue una pty, como las creadas por xterm
o ssh
, y el programa de control finaliza, cerrando el xterm o finalizando la conexión SSH ) , el programa fallará tan pronto como intente leer desde la entrada estándar o escribir en la salida estándar.
Lo que nohup
sí, por otro lado, es separar efectivamente el proceso del terminal:
- Cierra la entrada estándar (el programa no podrá leer ninguna entrada, incluso si se ejecuta en primer plano. No se detiene, pero recibirá un código de error o
EOF
).
- Redirige la salida estándar y el error estándar al archivo
nohup.out
, por lo que el programa no fallará al escribir en la salida estándar si el terminal falla, por lo que no se pierde lo que escriba el proceso.
- Impide que el proceso reciba un
SIGHUP
(de ahí el nombre).
Tenga en cuenta que nohup
no no eliminar el proceso de control de trabajo de la cáscara y también no lo pone en segundo plano (pero desde un plano nohup
de trabajo es más o menos inútil, que había por lo general lo puso en el fondo usando &
). Por ejemplo, a diferencia de disown
, el shell aún le dirá cuándo se ha completado el trabajo de nohup (a menos que el shell finalice antes, por supuesto).
Entonces para resumir:
&
pone el trabajo en segundo plano, es decir, lo bloquea al intentar leer la entrada y hace que el shell no espere a que se complete.
disown
elimina el proceso del control de trabajo del shell, pero aún lo deja conectado al terminal. Uno de los resultados es que el shell no lo enviará a SIGHUP
. Obviamente, solo se puede aplicar a trabajos en segundo plano, porque no se puede ingresar cuando se está ejecutando un trabajo en primer plano.
nohup
desconecta el proceso del terminal, redirige su salida nohup.out
y lo protege SIGHUP
. Uno de los efectos (el nombre) es que el proceso no recibirá ninguno enviado SIGHUP
. Es completamente independiente del control del trabajo y, en principio, podría usarse también para trabajos en primer plano (aunque eso no es muy útil).