sabato 27 novembre 2021

Come funzionano i segnali Linux: SIGINT, SIGTERM e SIGKILL

Shutterstock / SkillUp Gli interrupt software sui sistemi Linux e Unix vengono effettuati tramite segnali. Esistono molti segnali Linux diversi, ma alcuni si distinguono e sono importanti da comprendere e conoscere: SIGINT, SIGTERM e SIGKILL. Ecco come funzionano.

Cos’è un Linux Signal ? Sappiamo tutti che un semaforo rosso significa che dobbiamo smettere di camminare o guidare. Allo stesso modo, nei sistemi Linux e Unix, si può passare un segnale a un programma o servizio in esecuzione per interagire con esso. Ad esempio, si potrebbe inviare un segnale di semaforo rosso a un programma semplicemente emettendo un SIGTERM segnale.

Proprio come con un semaforo rosso, le persone possono scegliere di continuare camminare o guidare quando la luce è rossa. Anche se potrebbe non essere un’idea sicura per tutti i soggetti coinvolti, un SIGTERM il segnale inviato a un processo farà esattamente questo; il processo / programma può scegliere di ignorare tale segnale.

I segnali Linux di base hanno tutti un numero (1- 30 +). Dopo un po ‘di tempo, un utente Linux esperto ne conoscerà generalmente uno o più di questi. Ad esempio, il segnale SIGTERM corrisponde al numero 15 e il segnale 9 ( SIGKILL ) è probabilmente il più noto in quanto consente di terminare forzatamente un processo, a differenza del nostro SIGTERM esempio di luce rossa.

Qui vediamo il schermata principale di htop (puoi installare questa pratica utilità digitando sudo apt install htop su Ubuntu / Mint, o sudo yum install htop su RedHat / Centos / Fedora ) con un numero di terminazione e altri segnali (più in basso nell’elenco; sono presenti 37 in totale) che può essere inviato a un processo precedentemente selezionato a destra. È possibile selezionare un processo premendo il cursore su / giù e quindi inviare un segnale utilizzando F9.

SIGKILL & SIGTERM Anche se il nome può sembrare un po ‘sinistro, il gergo comune di Linux per la terminazione del processo è che uno “uccide” un processo. In generale, vogliamo solo terminare un processo con un – 9 ( SIGKILL ) se tale processo / programma è in sospeso. Nota che ogni volta che parliamo di processo o programma, le parole possono essere scambiate a piacimento. Fondamentalmente, un processo è qualsiasi programma (o servizio) in esecuzione a cui è stato assegnato un PID (un identificatore di processo).

Diamo un’occhiata a un esempio di terminazione di un processo in background in esecuzione utilizzando un SIGKILL al processo in esecuzione. Nota che come spiegato SIGKILL è piuttosto distruttivo e terminerà il processo indipendentemente da ciò che il processo vorrebbe fare con il segnale. Un certo numero di segnali può essere catturato e reindirizzato dal processo, mentre altri no.

Qui abbiamo iniziato un sleep 1800 in background (utilizzando & alla fine del comando), che è stato avviato come primo ( ) processo in background con PID 574660 . Successivamente abbiamo terminato il processo in background utilizzando kill -9 574660 , dove – 9 sta per SIGKILL .

Mentre il processo viene terminato immediatamente, non lo facciamo vedere il messaggio di terminazione (processo in background 1 ucciso, ad es. , + Killed ) poiché il prompt dei comandi ritorna prima che il messaggio venga visualizzato, ovvero, la restituzione della riga di comando è stata un’operazione più rapida rispetto alla conclusione del processo, oppure simile.

Controlliamo l’elenco dei processi cercando il PID ps -ef | grep 574660 . Sebbene ci sia un output, l’output mostrato è solo per il nostro grep in esecuzione comando; il processo sleep è già stato terminato.

Valutiamo lo stesso con SIGTERM , ovvero kill – 15 $ { PID} dove $ {PID} è il processo che vogliamo terminare.

Abbiamo dovuto premere Invio per attivare / mostrare il messaggio di terminazione (come spiegato sopra). Possiamo vedere che il programma è terminato di nuovo correttamente. Tuttavia, questa volta, sebbene invisibile per questo particolare esempio (continua a leggere!), Internamente all’interno del sleep codice del programma, le cose sono andate un po ‘diversamente.

In questo caso ( utilizzando – 15 ie SIGTERM , il sleep è stato notificato e ha avuto l’opportunità di gestire internamente il segnale. Successivamente potrebbe rispondere chiudendosi automaticamente, ignorando il segnale o con qualsiasi altra azione sviluppata nel codice. Possiamo anche dimostrare che ciò è vero controllando il segnale di uscita e / o l’uscita:

Qui abbiamo avviato il processo sleep 2000 due volte, quindi ha utilizzato un’altra sessione di shell / terminale per terminare il programma. La prima volta, abbiamo utilizzato kill -9 e il la seconda volta abbiamo usato kill – 15 per interrompere il processo sleep .

Notiamo immediatamente come l’output ritorni Ucciso nel primo ( kill -9 azione) istanza. Per il secondo tentativo (utilizzando kill – 15 ), vediamo invece l’uscita Terminata ; il programma si è terminato da solo. Successivamente alle rispettive terminazioni abbiamo anche controllato i segnali di uscita e abbiamo scoperto che i codici di uscita erano diversi.

Perché è questo importante? Considera programmi più grandi; in questo caso, stavamo solo terminando una semplice sleep comando. Non c’erano dati gestiti, traffico inviato avanti / indietro, ecc. Ma cosa accadrebbe se inviassimo un kill -9 al nostro server di database (questo generalmente richiederebbe privilegi sudo / root)?

Attiverebbe il database per entrare in modalità di ripristino da arresto anomalo del sistema al successivo avvio perché, per quanto ne sa il software del database, tutto ciò che è successo era “c’era” seguito da “Niente.” In altre parole, si è schiantato. Se invece avessimo emesso un kill – 15 , il software del database avrebbe potuto eseguire uno spegnimento controllato, ad esempio, bloccando prima la connessione di nuovi utenti, quindi disconnettendo / terminando gli utenti esistenti, quindi terminando la scrittura dei dati, ecc. prima di terminare definitivamente.

Invio di segnali Linux con sequenze di tastiera Sapevi che ogni volta che hai inviato un CTRL + c sequenza di tasti a un programma in esecuzione, ad esempio in un terminale, che invece un SIGINT è inviato? Torniamo al nostro comando fidato sleep e testalo :

Qui abbiamo iniziato sleep , quindi premere la combinazione di tasti CTRL + c . Il programma è terminato, o meglio è stato interrotto dal Segnale SIGINT inviato. Chiediamo il codice di uscita e confermiamo che ancora una volta il codice di uscita è diverso dai segnali precedenti.

Nota che questo il codice di uscita, per il sonno, sarà sempre abbinato al segnale inviato, sebbene potenzialmente non tutti i segnali potrebbero essere coperti. In altre parole, quando si utilizza CTRL + c al riga di comando il codice di uscita sarà sempre 130 , 137 se ucciso con kill -9 e 143 quando uccidi – 15 è stato utilizzato.

È possibile testare i codici di uscita per i comandi interrogando la variabile $? , che contiene il codice di uscita del comando precedente (purché non sia stato avviato un nuovo comando). Conoscere il codice di uscita di un dato comando in una particolare situazione, e / o come risultato di un particolare segnale inviato a quel comando, aiuta quando si creano script per soluzioni che gestiscono altri processi, ecc. (Che è il caso di molti script di shell, in particolare quando si gestiscono server o ambienti automatizzati).

Un’altra sequenza di tasti spesso utilizzata è CTRL + z . Questo invierà un segnale SIGTSTP , un segnale di sospensione che pone immediatamente un processo in sospensione fino a quando (ad esempio) viene emesso un comando ‘fg’ per lo stesso processo che lo riporterà in primo piano.

Per ulteriori informazioni sulla gestione dei processi, vedere Hacks di terminazione del processo Bash.

Avvolgendo In questo articolo, abbiamo esaminato i segnali Linux più importanti e come possiamo praticamente usarli in un ambiente Linux o Unix. Conoscere i segnali Linux di base aiuta con l’uso e la gestione quotidiana di Linux, ad esempio, quando un processo è in sospeso e deve essere terminato con kill -9 . In un prossimo articolo, potremmo esaminare l’acquisizione di un segnale utilizzando la trappola comando dall’interno di uno script Bash, che consente di definire una procedura personalizzata da eseguire quando viene emesso un tale segnale.

Se ti è piaciuto leggere questo articolo, dai un’occhiata alla nostra serie di automazione Bash a partire da Bash Automation & Scripting Basics. Nel terzo articolo di quella serie, discutiamo anche della gestione dei processi in background, accennata in precedenza in questo articolo.