
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.
Che cos'è un segnale Linux ?
Sappiamo tutti che una luce rossa 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 semaforo rosso a un programma emettendo semplicemente un segnale SIGTERM.
Proprio come con un semaforo rosso, le persone possono scegliere di continuare a camminare o guidare quando il semaforo è rosso . Anche se potrebbe non essere un'idea sicura per tutti i soggetti coinvolti, un segnale SIGTERM 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 esempio a luci rosse SIGTERM.
< img src = "http://www.cloudsavvyit.com/pagespeed_static/1.JiBnMqyl6S.gif" />
Qui vediamo la schermata principale di htop (puoi installare questa pratica utility digitando sudo apt install htop su Ubuntu/Mint, o sudo yum install htop su RedHat/Centos/Fedora) con un numero di terminazioni e altri segnali (più in basso nel elenco; ce ne sono 37 in totale) che possono essere inviati a un processo precedentemente selezionato a destra. È possibile selezionare un processo premendo il cursore su/giù e quindi inviare un segnale utilizzando F9.
SIGKILL & amp; SIGTERM
Anche se il nome può sembrare un po 'sinistro, il gergo comune di Linux per la terminazione del processo è quello & # 8216; kills & # 8217; un processo. In generale, desidereremo terminare un processo con un segnale -9 (SIGKILL) solo se tale processo/programma è 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).
Vediamo un esempio di terminazione di un processo in background in esecuzione utilizzando un segnale SIGKILL per il processo in esecuzione. Si noti 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 avviato uno sleep 1800 in background (usando & amp; alla fine del comando), che è stato avviato come primo ([1]) processo in background con PID 574660. Successivamente abbiamo terminato quel processo in background usando kill -9 574660, dove -9 sta per SIGKILL.
Mentre il processo viene terminato immediatamente, non vediamo il messaggio di terminazione (processo in background 1 ucciso, cioè [1] + Killed) quando il prompt dei comandi ritorna prima del viene visualizzato un messaggio, ovvero la restituzione della riga di comando è stata un'operazione più rapida rispetto alla terminazione del processo, o simile.
Controlliamo l'elenco dei processi grepping per il PID ps -ef | grep 574660. Sebbene ci sia un output, l'output mostrato è solo per il nostro comando grep in esecuzione; il processo di sospensione è 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 al codice del programma sleep, le cose sono andate un po 'diversamente.
In questo caso (usando -15 cioè SIGTERM per terminare il processo ), il processo di sospensione è 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'output:
Qui abbiamo avviato il processo sleep 2000 due volte, quindi abbiamo utilizzato un'altra sessione shell/terminale per terminare il programma. La prima volta abbiamo usato kill -9 e la seconda volta abbiamo usato kill -15 per interrompere il processo di sospensione.
Notiamo immediatamente come l'output restituisca Killed nella prima istanza (kill -9 action). Per il secondo tentativo (usando kill -15), vediamo invece l'output Terminated; 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é è importante? Considera programmi più grandi; in questo caso, stavamo solo terminando un semplice comando sleep. Non c'erano dati gestiti, nessun traffico inviato avanti/indietro, ecc. Ma cosa accadrebbe se inviassimo un comando kill -9 al nostro server database (questo generalmente richiederebbe privilegi a livello di root/sudo)?
Avrebbe attivato 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 & # 8220; era lì & # 8221; seguito da & # 8220; niente. & # 8221; In altre parole, si è schiantato. Se invece avessimo emesso un comando kill -15, il software del database avrebbe potuto eseguire uno spegnimento controllato, ad esempio, bloccando prima i nuovi utenti dalla connessione, quindi disconnettendo/terminando gli utenti esistenti, quindi terminare la scrittura dei dati, ecc. terminazione.
Invio di segnali Linux con sequenze di tastiera
Sapevi che ogni volta che hai inviato una sequenza di tasti CTRL + c a un programma in esecuzione, ad esempio in un terminale, viene invece inviato un SIGINT? Torniamo al nostro fidato comando sleep e testiamo questo:
Qui abbiamo ricominciato a dormire, quindi abbiamo premuto 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 codice di uscita, per il sonno, sarà sempre abbinato al segnale inviato, anche se potenzialmente non tutti i segnali può essere coperto. In altre parole, quando si utilizza CTRL + c nella riga di comando, il codice di uscita sarà sempre 130, 137 se ucciso con kill -9 e 143 quando è stato usato kill -15.
Puoi testare i codici di uscita per i comandi interrogando $? variabile, che contiene il codice di uscita del comando precedente (a condizione che 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 tastiera usata spesso è CTRL + z. Questo invierà un segnale SIGTSTP, un segnale di sospensione che pone immediatamente un processo in sospensione fino a quando (per esempio) non viene emesso un comando 'fg' per lo stesso processo che lo riporterà in primo piano.
A per ulteriori informazioni sulla gestione dei processi, vedere Hacks di terminazione del processo Bash.
Conclusione
In questo articolo, abbiamo esaminato i più importanti Segnali Linux 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 la possibilità di catturare un segnale utilizzando il comando trap dall'interno di uno script Bash, consentendo di definire una procedura personalizzata da eseguire quando viene emesso un tale segnale.
Se ti è piaciuto leggere in questo articolo, dai un'occhiata alla nostra serie di automazione Bash a partire da Bash Automation & amp; Nozioni di base sullo scripting. Nel terzo articolo di quella serie, discutiamo anche della gestione dei processi in background, accennata in precedenza in questo articolo.