Bash scripting - segnali

Versione del 22 lug 2014 alle 12:31 di S3v (discussione | contributi) (- template "Versioni compatibili")
Bash scripting

Sommario

  1. Introduzione
  2. Comandi essenziali
  3. Variabili (stringhe)
  4. Caratteri di escape, apici e virgolette
  5. Espansioni in stringhe quotate
  6. Espansioni non quotabili
  7. Istruzioni composte
  8. Funzioni
  9. File descriptor e redirezioni
  10. Segnali

Segnali

Ogni processo in Unix e Unix-like può ricevere dei segnali da altri processi (se appartengono allo stesso utente oppure da root). Di seguito i principali, tra quelli previsti da POSIX:

  • INT : è equivalente a Ctrl-c da tastiera, per uno script associato a un terminale, se non è eseguito in background. L'azione di default è la terminazione;
  • QUIT : è equivalente a Ctrl-\ da tastiera, per uno script associato a un terminale, se non è eseguito in background. L'azione di default è la terminazione con core dump;
  • HUP : è equivalente a chiudere il terminale, per uno script associato a un terminale, anche se eseguito in background; o in generale alla morte di un processo padre. Viene inviato automaticamente, e l'azione di default è la terminazione;
  • TERM : è il segnale di terminazione di default. L'azione di default è la terminazione;
  • KILL : è un segnale di terminazione che non può essere ignorato (si veda trap). L'unica azione che sarà eseguita è la sua terminazione immediata;
  • PIPE : è il segnale ricevuto da un processo che invia l'output a una pipe, quando il processo lettore ha terminato. Viene inviato automaticamente, e l'azione di default è la terminazione;
  • ABRT : è il segnale di abort. L'azione di default è la terminazione con core dump;
  • STOP : è equivalente a Ctrl-z da tastiera, per uno script associato a un terminale non eseguito in background, ma come KILL non può mai essere ignorato (si veda trap). L'unica azione che sarà eseguita è la sua interruzione immediata;
  • CONT : è il segnale per continuare l'esecuzione per un processo interrotto. Se il processo non è interrotto, di default il segnale è ignorato;
  • TSTP : è equivalente a Bloc Scor (o Ctrl-s; per riprendere: Ctrl-q), per bloccare l'output. L'azione di default è interrompere il processo;
  • CHLD : è il segnale che un processo figlio è terminato. Viene inviato automaticamente, e di default è ignorato;
  • WINCH : è il segnale che la finestra del terminale è stata ridimensionata. Viene inviato automaticamente, e di default è ignorato;
  • USR1 : è un segnale lasciato da definire all'utente. L'azione di default è la terminazione;
  • USR2 : è un segnale lasciato da definire all'utente. L'azione di default è la terminazione.

Il core dump è un dump dello stato (o una sua parte) del processo terminato, a scopo di debug. Può essere limitato e anche disattivato interamente. Se non attivo, l'azione eseguita è equivalente a una terminazione senza core dump.

Invio di segnali

Alcuni segnali vengono inviati automaticamente, al sussistere di determinate condizioni, ma possono anche essere inviati esplicitamente con il comando kill come tutti gli altri.
Sintassi: kill [ -s SIGNAL ] pid
Invia un segnale (di default: TERM) al processo con il pid scelto. Si noti che l'invio è asincrono, ossia kill non resta in attesa che il processo con pid scelto effettui l'azione associata al segnale. Di conseguenza il comando ha sempre successo, salvo che il pid non esista o non possa ricevere il segnale (per esempio perché non è dello stesso utente).

Cattura dei segnali

Le azioni da intraprendere possono essere modificati con l'istruzione trap.
Sintassi: trap 'stringa' SIGNAL1 [ ... ]
Cattura i segnali (se possibile, non lo è per KILL e STOP), con il seguente comportamento:

  • se la stringa è il solo carattere -, le azioni associate alla lista di segnali sono impostate nuovamente come quelle di default per i segnali;
  • se la stringa è vuota, i segnali verranno ignorati;
  • se la stringa è il nome di una funzione, verrà eseguita ogni volta che uno dei segnali viene ricevuto. L'azione normale è sovrascritta, quindi se è necessario preservarla dopo la funzione, dovrà occuparsene la funzione stessa (per esempio di uscire con exit dopo aver effettuato la pulizia);
  • il segnale può essere EXIT, che ha significato solo per questa istruzione, in tal caso la funzione sarà eseguita alla fine dello script, che può essere causata anche da segnali (con l'unica eccezione di KILL), purché lo script non termini con un exec seguito da un eseguibile.
  ATTENZIONE
Al posto di 'stringa' nell'istruzione trap può esserci un qualsiasi comando, ma si consiglia l'uso di una funzione sia per chiarezza del codice, sia soprattutto per evitare la doppia interpretazione con possibili espansioni in fase di definizione di trap prima e di esecuzione del comando poi. Un uso diverso ha la stessa pericolosità di eval, e può portare a code injection e privilege escalation.


Un esempio classico di trap:

clean () {
    # funzione di pulizia
    ...
}

trap 'clean' EXIT   # la funzione clean è eseguita se si riceve un segnale di terminazione
...
if comando; then
    exec eseguibile # clean NON è eseguita dopo exec e un eseguibile
fi
...
exit 0              # clean è eseguita anche con exit

In caso di esecuzione di una subshell le azioni da intraprendere in seguito alla ricezione di un segnale vengono reimpostate al loro valore di default, ma i segnali ignorati continuano a restare ignorati.




Guida scritta da: HAL 9000 13:10, 22 lug 2014 (CEST)   Debianized 20%
Estesa da:
Verificata da:

Verificare ed estendere la guida | Cos'è una guida Debianized