La risposta di @hvd è sostanzialmente corretta. Per eseguire il backup ancora di più, il init
processo invierà prima SIGTERM
ai processi quando si spegne il computer, quindi dopo un ritardo verrà inviato SIGKILL
se non sono già usciti. I processi non possono gestire / ignorare SIGKILL
.
Per dare un po 'più di dettagli, la vera risposta è che non hai modo di sapere con certezza che il programma lo gestisce. SIGTERM
è il segnale più comune da utilizzare per chiedere educatamente a un programma di uscire, ma tutta la gestione del segnale dipende dal fatto che il programma esegua qualcosa con il segnale.
Per dirla in un modo diverso, basato sulle altre risposte, se avessi un programma scritto da @Jos o da @AlexGreg, presumibilmente avrebbero gestito SIGQUIT
ma forse no SIGTERM
, e quindi l'invio SIGTERM
sarebbe meno "morbido" di SIGQUIT
.
Ho scritto del codice in modo che tu possa giocarci da solo. Salvare il seguito come signal-test.c
, quindi compilare con
gcc -o signal-test signal-test.c
È quindi possibile eseguirlo ./signal-test
e vedere cosa succede quando si inviano segnali diversi con killall -s <signal>
.
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
int flag = 0;
void handle_signal(int s)
{
flag = s;
}
int main(int argc, char *argv[])
{
signal(SIGTERM, handle_signal);
signal(SIGQUIT, handle_signal);
while(flag == 0){
sleep(1);
}
printf("flag is %d\n", flag);
return flag;
}
Allo stato attuale, il codice gestisce sia SIGTERM che SIGQUIT con garbo. Potresti provare a commentare le linee signal(SIG...
(usando //
a all'inizio della linea) per rimuovere il gestore del segnale, quindi eseguire e inviare nuovamente i segnali. Dovresti essere in grado di vedere questi diversi output:
$ ./signal-test
Terminated
$ ./signal-test
Quit (core dumped)
$ ./signal-test
flag is 15
$ ./signal-test
flag is 3
a seconda che tu gestisca o meno i segnali.
Potresti anche provare a ignorare i segnali:
signal(SIGTERM, SIG_IGN);
Se lo fai, l'invio SIGTERM
non farà nulla, dovrai SIGKILL
terminare il processo.
Maggiori dettagli in man 7 signal
. Si noti che l'utilizzo signal()
in questo modo è considerato non portatile, ma è molto più facile dell'alternativa!
Un'altra nota in calce minore: Solaris killall
tenta di uccidere tutti i processi. Tutti loro. Se lo esegui come root, potresti essere sorpreso :)