Qual è la differenza tra l'esecuzione di un programma come demone e il fork in background con '&'?


Risposte:


31

Il modo tradizionale di demonizzare è:

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

Ciò garantisce che il processo non si trovi più nello stesso gruppo di processi del terminale e quindi non verrà ucciso insieme ad esso. Il reindirizzamento IO serve a far sì che l'uscita non appaia sul terminale.


5
quindi se un terminale che genera un processo in background (&) viene chiuso, anche il processo in background terminerà?
user1561108,

9
Il processo riceverà SIGHUP all'uscita del terminale, il gestore predefinito per quel segnale è di terminare il processo.
Dennis Kaarsemaker,

12
Aggiungi la &spiegazione della parte alla tua risposta. Sembra essere incompleto .. se controlli la domanda originale.
mtk,

1
Questo perché eseguire le cose in background con e non rende il processo fare qualcosa di speciale :)
Dennis Kaarsemaker,

34

Per un demone, quello che vuoi è un processo che non ha legami con nulla. Per lo meno, vuoi che sia nella sua stessa sessione, non essere collegato a un terminale, non avere alcun descrittore di file ereditato dal genitore aperto a nulla, non avere un genitore che si prende cura di te (diverso da init) avere la corrente directory in /modo da non impedire un umount ...

Per staccare da un terminale, si crea una nuova sessione, tuttavia, per creare una sessione, non è necessario essere un leader di gruppo (o sessione), quindi la cosa migliore è forkare un nuovo processo. Supponendo che il genitore esca, ciò significa anche che il processo non avrà più un genitore e sarà adottato da init. Quindi, chiudi tutti i possibili descrittori di file, tu chdir("/")(non puoi chiudere la directory di lavoro corrente per rilasciare quella risorsa come per i descrittori di file, rendendo /almeno le directory di lavoro correnti non impedisce lo smontaggio delle directory).

Poiché quel processo è un leader di sessione, c'è il rischio che se mai apre un dispositivo terminale, diventa il processo di controllo di quel terminale. Il fork di una seconda volta assicura che non accada.

Dall'altro lato, &, nelle shell interattive, esegue il fork e crea un nuovo gruppo di processi (in modo da non far parte del gruppo di processi in primo piano del terminale) e nelle shell non interattive, crea un processo e ignora SIGINT in esso. Non si stacca dal terminale, non chiude i descrittori di file (anche se alcune shell riapriranno stdin in /dev/null) ...


a che cosa serve chdir ("/")? chiudere il descrittore di file?
Timothy Leung,

@TimothyLeung, vedi modifica.
Stéphane Chazelas,

8

La differenza tra l'esecuzione di un programma / processo come demone e l'inoltro in background utilizzando la e commerciale è sostanzialmente correlata alla proprietà.

Molto spesso, il processo padre di un demone è il processo init (il primo processo che deve essere avviato su un sistema Unix), poiché il demone è figlio di quel processo significa che non è sotto il tuo controllo diretto come utente non privilegiato . D'altra parte, il fork di un programma / processo in background significa che è possibile in qualsiasi momento richiamarlo in primo piano e / o ucciderlo.


1
Inoltre, per rispondere al lato tecnico sopra descritto di scollegare un processo anziché tenerlo come figlio del terminale, puoi provare a eseguire "nohup firefox &"
Odaym

7

Con il command &tuo processo verrà ucciso da un segnale SIGHUP quando il genitore muore.

Tuttavia, gli amministratori di sistema hanno accesso ad alcune soluzioni alternative.

Su un sistema bash, puoi usare:

(trap '' HUP; command) &

Questo apre una subshell, intrappola il HUPsegnale con un gestore vuoto e lo sostituisce / lo scambia.

L'output potrebbe comunque essere reindirizzato a errato tty. O perdersi.
Si può rimediare con &>command.out, 1>output.outo2>errors.out

Potresti anche avere accesso, sulla maggior parte dei sistemi, al nohupcomando.
nohupsemplifica notevolmente questo processo. È abbastanza standard, ma ho riscontrato che mancano molte distribuzioni ARM di busybox. Scrivi solo:

nohup command &

..e hai finito. L'output viene reindirizzato, IIRC, nohup.outma questo nome file può essere modificato con un'opzione.


2
Solo per notare che con ZSH puoi separare un command &successivo dalla shell con il disownquale poi funziona come un post-nohup.
matematica
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.