SIGTERM e SIGKILL sono destinati a richieste generiche di "terminare questo processo". SIGTERM (per impostazione predefinita) e SIGKILL (sempre) causeranno la terminazione del processo. SIGTERM può essere catturato dal processo (ad esempio in modo che possa eseguire la propria pulizia se lo desidera) o addirittura ignorato completamente; ma SIGKILL non può essere catturato o ignorato.
SIGINT e SIGQUIT sono destinati specificatamente alle richieste provenienti dal terminale:è possibile assegnare particolari caratteri di input per generare questi segnali (a seconda delle impostazioni di controllo del terminale). L'azione predefinita per SIGINT è lo stesso tipo di terminazione del processo dell'azione predefinita per SIGTERM e dell'azione immutabile per SIGKILL; anche l'azione predefinita per SIGQUIT è la terminazione del processo, ma possono verificarsi ulteriori azioni definite dall'implementazione, come la generazione di un core dump. Entrambi possono essere rilevati o ignorati dal processo, se necessario.
SIGHUP, come dici tu, ha lo scopo di indicare che la connessione del terminale è stata persa, piuttosto che essere un segnale di terminazione in quanto tale. Ma, ancora una volta, l'azione predefinita per SIGHUP (se il processo non lo rileva o lo ignora) è terminare il processo allo stesso modo di SIGTERM ecc. .
C'è una tabella nelle definizioni POSIX per signal.h
che elenca i vari segnali e le loro azioni e scopi predefiniti, e il capitolo Interfaccia terminale generale include molti più dettagli sui segnali relativi al terminale.
Come ha notato DarkDust, molti segnali hanno gli stessi risultati, ma i processi possono associare loro azioni diverse distinguendo come viene generato ciascun segnale. Osservando il codice sorgente del kernel di FreeBSD (kern_sig.c) vedo che i due segnali vengono gestiti allo stesso modo, terminano il processo e vengono consegnati a qualsiasi thread.
SA_KILL|SA_PROC, /* SIGINT */
SA_KILL|SA_PROC, /* SIGTERM */
man 7 signal
Questa è la comoda manpage non normativa del progetto Linux man-pages che spesso vuoi cercare per informazioni sui segnali di Linux.
La versione 3.22 menziona cose interessanti come:
I segnali SIGKILL e SIGSTOP non possono essere rilevati, bloccati o ignorati.
e contiene la tabella:
Signal Value Action Comment
----------------------------------------------------------------------
SIGHUP 1 Term Hangup detected on controlling terminal
or death of controlling process
SIGINT 2 Term Interrupt from keyboard
SIGQUIT 3 Core Quit from keyboard
SIGILL 4 Core Illegal Instruction
SIGABRT 6 Core Abort signal from abort(3)
SIGFPE 8 Core Floating point exception
SIGKILL 9 Term Kill signal
SIGSEGV 11 Core Invalid memory reference
SIGPIPE 13 Term Broken pipe: write to pipe with no
readers
SIGALRM 14 Term Timer signal from alarm(2)
SIGTERM 15 Term Termination signal
SIGUSR1 30,10,16 Term User-defined signal 1
SIGUSR2 31,12,17 Term User-defined signal 2
SIGCHLD 20,17,18 Ign Child stopped or terminated
SIGCONT 19,18,25 Cont Continue if stopped
SIGSTOP 17,19,23 Stop Stop process
SIGTSTP 18,20,24 Stop Stop typed at tty
SIGTTIN 21,21,26 Stop tty input for background process
SIGTTOU 22,22,27 Stop tty output for background process
che riassume il segnale Action
che distingue ad es. SIGQUIT da SIGQUIT, poiché SIGQUIT ha l'azione Core
e SIGINT Term
.
Le azioni sono documentate nello stesso documento:
The entries in the "Action" column of the tables below specify the default disposition for each signal, as follows:
Term Default action is to terminate the process.
Ign Default action is to ignore the signal.
Core Default action is to terminate the process and dump core (see core(5)).
Stop Default action is to stop the process.
Cont Default action is to continue the process if it is currently stopped.
Non riesco a vedere alcuna differenza tra SIGTERM e SIGINT dal punto di vista del kernel poiché entrambi hanno l'azione Term
ed entrambi possono essere catturati. Sembra che sia solo una "distinzione di convenzione d'uso comune":
- SIGINT è ciò che accade quando fai CTRL-C dal terminale
- SIGTERM è il segnale predefinito inviato da
kill
Alcuni segnali sono ANSI C e altri no
Una differenza considerevole è che:
- SIGINT e SIGTERM sono ANSI C, quindi più portabili
- SIGQUIT e SIGKILL non lo sono
Sono descritti nella sezione "7.14 Gestione dei segnali" della bozza C99 N1256:
- SIGINT ricezione di un segnale di attenzione interattivo
- SIGTERM una richiesta di terminazione inviata al programma
il che rende SIGINT un buon candidato per un Ctrl + C.
interattivoPOSIX 7
POSIX 7 documenta i segnali con signal.h
intestazione:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html
Questa pagina ha anche la seguente tabella di interesse che menziona alcune delle cose che avevamo già visto in man 7 signal
:
Signal Default Action Description
SIGABRT A Process abort signal.
SIGALRM T Alarm clock.
SIGBUS A Access to an undefined portion of a memory object.
SIGCHLD I Child process terminated, stopped,
SIGCONT C Continue executing, if stopped.
SIGFPE A Erroneous arithmetic operation.
SIGHUP T Hangup.
SIGILL A Illegal instruction.
SIGINT T Terminal interrupt signal.
SIGKILL T Kill (cannot be caught or ignored).
SIGPIPE T Write on a pipe with no one to read it.
SIGQUIT A Terminal quit signal.
SIGSEGV A Invalid memory reference.
SIGSTOP S Stop executing (cannot be caught or ignored).
SIGTERM T Termination signal.
SIGTSTP S Terminal stop signal.
SIGTTIN S Background process attempting read.
SIGTTOU S Background process attempting write.
SIGUSR1 T User-defined signal 1.
SIGUSR2 T User-defined signal 2.
SIGTRAP A Trace/breakpoint trap.
SIGURG I High bandwidth data is available at a socket.
SIGXCPU A CPU time limit exceeded.
SIGXFSZ A File size limit exceeded.
Init BusyBox
reboot
predefinito di BusyBox 1.29.2 Il comando invia un SIGTERM ai processi, dorme per un secondo e quindi invia SIGKILL. Questa sembra essere una convenzione comune in diverse distribuzioni.
Quando spegni un sistema BusyBox con:
reboot
invia un segnale al processo init.
Quindi, il gestore del segnale init finisce per chiamare:
static void run_shutdown_and_kill_processes(void)
{
/* Run everything to be run at "shutdown". This is done _prior_
* to killing everything, in case people wish to use scripts to
* shut things down gracefully... */
run_actions(SHUTDOWN);
message(L_CONSOLE | L_LOG, "The system is going down NOW!");
/* Send signals to every process _except_ pid 1 */
kill(-1, SIGTERM);
message(L_CONSOLE, "Sent SIG%s to all processes", "TERM");
sync();
sleep(1);
kill(-1, SIGKILL);
message(L_CONSOLE, "Sent SIG%s to all processes", "KILL");
sync();
/*sleep(1); - callers take care about making a pause */
}
che stampa sul terminale:
The system is going down NOW!
Sent SIGTERM to all processes
Sent SIGKILL to all processes
Ecco un minimo esempio concreto di ciò.
Segnali inviati dal kernel
- SIGKILL:
- OOM killer:cos'è RSS e VSZ nella gestione della memoria di Linux