¿Cuál es la diferencia entre ejecutar un programa como demonio y bifurcarlo en segundo plano con '&'?

Respuestas:

31

La forma tradicional de demonizar es:

fork()
setsid()
close(0) /* and /dev/null as fd 0, 1 and 2 */
close(1)
close(2)
fork()

Esto garantiza que el proceso ya no esté en el mismo grupo de procesos que el terminal y, por lo tanto, no se eliminará junto con él. La redirección de IO es hacer que la salida no aparezca en el terminal.

Dennis Kaarsemaker
fuente
55
entonces, si un terminal que genera un proceso en segundo plano (&) está cerrado, ¿el proceso en segundo plano también finalizará?
user1561108
99
El proceso recibirá SIGHUP cuando el terminal salga, el controlador predeterminado para esa señal es terminar el proceso.
Dennis Kaarsemaker
12
Agregue la &explicación de la parte a su respuesta. Parece estar incompleto ... si revisas la pregunta original.
mtk
1
Eso es porque ejecutar las cosas en segundo plano con y no hace que el proceso haga nada especial :)
Dennis Kaarsemaker
34

Para un demonio, lo que quieres es un proceso que no tenga relación con nada. Por lo menos, desea que esté en su propia sesión, que no esté conectado a una terminal, que no tenga ningún descriptor de archivo heredado del padre abierto a nada, que no tenga un padre que se ocupe de usted (que no sea init). en el directorio /para no evitar un montaje ...

Para desconectarse de una terminal, crea una nueva sesión, sin embargo, para crear una sesión, no debe ser un líder de grupo (o sesión), por lo que lo mejor es bifurcar un nuevo proceso. Suponiendo que el padre salga, eso también significa que el proceso ya no tendrá un padre y será adoptado por init. Luego, cierre todos los descriptores de archivo posibles, usted chdir("/")(uno no puede cerrar el directorio de trabajo actual para liberar ese recurso como para los descriptores de archivo, haciendo que /los directorios de trabajo actuales al menos no impidan el desmontaje de directorios).

Debido a que ese proceso es un líder de sesión, existe el riesgo de que si alguna vez abre un dispositivo terminal, se convierta en el proceso de control de ese terminal. Bifurcar por segunda vez asegura que no suceda.

En el otro extremo, &, en shells interactivos, se bifurca y crea un nuevo grupo de procesos (para no estar en el grupo de procesos en primer plano del terminal), y en shells no interactivos, bifurca un proceso e ignora SIGINT en él. No se separa del terminal, no cierra los descriptores de archivo (aunque algunos shells volverán a abrir stdin /dev/null) ...

Stéphane Chazelas
fuente
¿De qué sirve chdir ("/")? cerrar el descriptor de archivo?
Timothy Leung
@TimothyLeung, ver edición.
Stéphane Chazelas
8

La diferencia entre ejecutar un programa / proceso como un demonio y bifurcarlo en segundo plano usando el ampersand está básicamente relacionado con la propiedad.

Muy a menudo, el proceso padre de un demonio es el proceso init (el primer proceso que se inicia en un sistema Unix), el demonio es un hijo de ese proceso, lo que significa que no está bajo su control directo como usuario no privilegiado. . Mientras que, por otro lado, bifurcar un programa / proceso en segundo plano significa que en cualquier momento puede volver a llamarlo en primer plano y / o matarlo.

Odaym
fuente
1
También para responder a la parte técnica anterior de separar un proceso en lugar de mantenerlo como un hijo del terminal, puede intentar ejecutar "nohup firefox &"
Odaym
7

With command &Your process será eliminado por una señal SIGHUP cuando el padre muera.

Sin embargo, los administradores de sistemas tienen acceso a algunas soluciones.

En un sistema bash, puede usar:

(trap '' HUP; command) &

Esto abre una subshell, atrapa la HUPseñal con un controlador vacío y la distribuye / bifurca.

La salida aún puede ser redirigida al error tty. O perderse.
Usted puede arreglar eso con &>command.out, 1>output.outo2>errors.out

También puede tener acceso, en la mayoría de los sistemas, al nohupcomando.
nohupsimplifica enormemente este proceso. Es bastante estándar, pero encontré que muchas distribuciones ARM incrustadas busybox no lo tienen. Solo escribes:

nohup command &

..y tu estas listo. La salida se redirige, IIRC, a nohup.out, pero este nombre de archivo se puede cambiar con una opción.

ZJR
fuente
2
Solo para notar que con ZSH puede desacoplar un command &shell posterior con el disownque luego funciona como un post-nohup.
matemáticas