Unix / Linux - Segnali e trap
In questo capitolo, discuteremo in dettaglio di segnali e trap in Unix.
I segnali sono interruzioni software inviate a un programma per indicare che si è verificato un evento importante. Gli eventi possono variare dalle richieste dell'utente agli errori di accesso alla memoria illegale. Alcuni segnali, come il segnale di interruzione, indicano che un utente ha chiesto al programma di fare qualcosa che non rientra nel normale flusso di controllo.
La tabella seguente elenca i segnali comuni che potresti incontrare e che desideri utilizzare nei tuoi programmi:
Nome segnale | Numero di segnale | Descrizione |
---|---|---|
SIGHUP | 1 | Riagganciare rilevato sul terminale di controllo o morte del processo di controllo |
SIGINT | 2 | Emesso se l'utente invia un segnale di interruzione (Ctrl + C) |
SIGQUIT | 3 | Emesso se l'utente invia un segnale di chiusura (Ctrl + D) |
SIGFPE | 8 | Emesso se viene tentata un'operazione matematica illegale |
SIGKILL | 9 | Se un processo riceve questo segnale, deve chiudersi immediatamente e non eseguirà alcuna operazione di pulizia |
SIGALRM | 14 | Segnale sveglia (utilizzato per i timer) |
SIGTERM | 15 | Segnale di terminazione software (inviato da kill per impostazione predefinita) |
Elenco dei segnali
C'è un modo semplice per elencare tutti i segnali supportati dal tuo sistema. Basta emettere il filekill -l comando e visualizzerà tutti i segnali supportati -
$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL
5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE
9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2
13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT
17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU
25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH
29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN
35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4
39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12
47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14
51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10
55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6
59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
L'elenco effettivo dei segnali varia tra Solaris, HP-UX e Linux.
Azioni predefinite
Ad ogni segnale è associata un'azione predefinita. L'azione predefinita per un segnale è l'azione che uno script o un programma esegue quando riceve un segnale.
Alcune delle possibili azioni predefinite sono:
Termina il processo.
Ignora il segnale.
Dump core. Questo crea un file chiamatocore contenente l'immagine di memoria del processo quando ha ricevuto il segnale.
Interrompi il processo.
Continua un processo interrotto.
Invio di segnali
Esistono diversi metodi per inviare segnali a un programma o uno script. Uno dei più comuni è che un utente digitiCONTROL-C o il INTERRUPT key mentre uno script è in esecuzione.
Quando si preme il pulsante Ctrl+C chiave, a SIGINT viene inviato allo script e come da script di azione predefinito definito termina.
L'altro metodo comune per fornire i segnali è utilizzare il kill command, la cui sintassi è la seguente -
$ kill -signal pid
Qui signal è il numero o il nome del segnale da trasmettere e pidè l'ID del processo a cui deve essere inviato il segnale. Ad esempio -
$ kill -1 1001
Il comando precedente invia il segnale HUP o di riaggancio al programma in esecuzione con process ID 1001. Per inviare un segnale di kill allo stesso processo, utilizzare il seguente comando:
$ kill -9 1001
Questo uccide il processo in esecuzione con process ID 1001.
Segnali di intrappolamento
Quando si preme il tasto Ctrl + C o Break sul terminale durante l'esecuzione di un programma shell, normalmente quel programma viene immediatamente terminato e il prompt dei comandi ritorna. Questo potrebbe non essere sempre desiderabile. Ad esempio, potresti finire per lasciare un mucchio di file temporanei che non verranno ripuliti.
Il trapping di questi segnali è abbastanza semplice e il comando trap ha la seguente sintassi:
$ trap commands signals
Qui command può essere qualsiasi comando Unix valido, o anche una funzione definita dall'utente, e signal può essere un elenco di qualsiasi numero di segnali che si desidera intercettare.
Ci sono due usi comuni per trap negli script di shell:
- Elimina i file temporanei
- Ignora i segnali
Pulizia dei file temporanei
Come esempio del comando trap, quanto segue mostra come rimuovere alcuni file e poi uscire se qualcuno cerca di interrompere il programma dal terminale -
$ trap "rm -f $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 2
Dal punto nel programma shell in cui viene eseguita questa trap, i due file work1$$ e dataout$$ verrà automaticamente rimosso se il segnale numero 2 viene ricevuto dal programma.
Quindi, se l'utente interrompe l'esecuzione del programma dopo che questa trap è stata eseguita, si può essere certi che questi due file verranno cancellati. Ilexit comando che segue il rm è necessario perché senza di esso l'esecuzione continuerebbe nel programma dal punto in cui si è interrotta quando è stato ricevuto il segnale.
Il segnale numero 1 viene generato per hangup. O qualcuno riattacca intenzionalmente la linea o la linea viene scollegata accidentalmente.
È possibile modificare la trappola precedente per rimuovere anche i due file specificati in questo caso aggiungendo il segnale numero 1 all'elenco dei segnali -
$ trap "rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 1 2
Ora questi file verranno rimossi se la linea viene interrotta o se viene premuto il tasto Ctrl + C.
I comandi specificati per trap devono essere racchiusi tra virgolette, se contengono più di un comando. Si noti inoltre che la shell esegue la scansione della riga di comando nel momento in cui viene eseguito il comando trap e anche quando viene ricevuto uno dei segnali elencati.
Pertanto, nell'esempio precedente, il valore di WORKDIR e $$verrà sostituito nel momento in cui viene eseguito il comando trap. Se si desidera che questa sostituzione avvenga nel momento in cui è stato ricevuto il segnale 1 o 2, è possibile inserire i comandi tra virgolette singole -
$ trap 'rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit' 1 2
Ignorare i segnali
Se il comando elencato per trap è nullo, il segnale specificato verrà ignorato quando ricevuto. Ad esempio, il comando -
$ trap '' 2
Questo specifica che il segnale di interruzione deve essere ignorato. Potresti voler ignorare alcuni segnali quando esegui un'operazione che non vuoi essere interrotta. È possibile specificare più segnali da ignorare come segue:
$ trap '' 1 2 3 15
Si noti che il primo argomento deve essere specificato affinché un segnale venga ignorato e non equivale a scrivere quanto segue, che ha un significato separato -
$ trap 2
Se ignori un segnale, anche tutte le subshell ignorano quel segnale. Tuttavia, se si specifica un'azione da intraprendere alla ricezione di un segnale, tutte le subshell eseguiranno comunque l'azione predefinita alla ricezione di quel segnale.
Ripristino delle trap
Dopo aver modificato l'azione predefinita da intraprendere alla ricezione di un segnale, è possibile modificarla nuovamente con la trappola se si omette semplicemente il primo argomento; così -
$ trap 1 2
Ciò ripristina l'azione da intraprendere alla ricezione dei segnali 1 o 2 al valore predefinito.