Ricerca…


Sintassi

  • trap action sigspec ... # Esegui "action" su un elenco di segnali
  • trap sigspec ... # Omitting action reimposta i trap per i segnali

Parametri

Parametro Senso
-p Elenca le trap attualmente installate
-l Elenca i nomi dei segnali e i numeri corrispondenti

Osservazioni

L'utilità trap è un built-in shell speciale. È definito in POSIX , ma bash aggiunge anche alcune estensioni utili.

Gli esempi compatibili con POSIX iniziano con #!/bin/sh e gli esempi che iniziano con #!/bin/bash usano un'estensione bash.

I segnali possono essere sia un numero di segnale, un nome di segnale (senza il prefisso SIG), o la parola chiave speciale EXIT .

Quelle garantite da POSIX sono:

Numero Nome Gli appunti
0 USCITA Esegui sempre all'uscita dalla shell, indipendentemente dal codice di uscita
1 SIGHUP
2 SIGINT Questo è ciò che ^C invia
3 SIGQUIT
6 SIGABRT
9 SIGKILL
14 SIGALRM
15 SIGTERM Questo è ciò che kill invia di default

Cattura SIGINT o Ctl + C

La trappola viene reimpostata per le subshell, quindi il sleep agirà comunque sul segnale SIGINT inviato da ^C (solitamente chiudendo), ma il processo genitore (cioè lo script della shell) non lo farà.

#!/bin/sh

# Run a command on signal 2 (SIGINT, which is what ^C sends)
sigint() {
    echo "Killed subshell!"
}
trap sigint INT

# Or use the no-op command for no output
#trap : INT

# This will be killed on the first ^C
echo "Sleeping..."
sleep 500

echo "Sleeping..."
sleep 500

E una variante che ti consente ancora di uscire dal programma principale premendo ^C due volte in un secondo:

last=0
allow_quit() {
    [ $(date +%s) -lt $(( $last + 1 )) ] && exit
    echo "Press ^C twice in a row to quit"
    last=$(date +%s)
}
trap allow_quit INT

Introduzione: ripulire i file temporanei

È possibile utilizzare il comando trap per "trap" i segnali; questo è l'equivalente di shell della chiamata signal() o sigaction() in C e la maggior parte degli altri linguaggi di programmazione per rilevare i segnali.

Uno degli usi più comuni di trap è quello di pulire i file temporanei sia in uscita prevista che inattesa.

Sfortunatamente non bastano script di shell per fare questo :-(

#!/bin/sh

# Make a cleanup function
cleanup() {
  rm --force -- "${tmp}"
}

# Trap the special "EXIT" group, which is always run when the shell exits.
trap cleanup EXIT

# Create a temporary file
tmp="$(mktemp -p /tmp tmpfileXXXXXXX)"

echo "Hello, world!" >> "${tmp}"

# No rm -f "$tmp" needed. The advantage of using EXIT is that it still works
# even if there was an error or if you used exit.

Accumula un elenco di operazioni di trap da eseguire all'uscita.

Ti sei mai dimenticato di aggiungere una trap per pulire un file temporaneo o eseguire altri lavori all'uscita?

Hai mai impostato una trappola che ne ha annullato un'altra?

Questo codice semplifica l'aggiunta di elementi da eseguire all'uscita di un elemento alla volta, piuttosto che avere un'istruzione trap grandi dimensioni da qualche parte nel codice, che potrebbe essere facile da dimenticare.

# on_exit and add_on_exit
# Usage:
#   add_on_exit rm -f /tmp/foo
#   add_on_exit echo "I am exiting"
#   tempfile=$(mktemp)
#   add_on_exit rm -f "$tempfile"
# Based on http://www.linuxjournal.com/content/use-bash-trap-statement-cleanup-temporary-files
function on_exit()
{
    for i in "${on_exit_items[@]}"
    do
        eval $i
    done
}
function add_on_exit()
{
    local n=${#on_exit_items[*]}
    on_exit_items[$n]="$*"
    if [[ $n -eq 0 ]]; then
        trap on_exit EXIT
    fi
}

Killing Child Processes in uscita

Le espressioni trap non devono essere singole funzioni o programmi, ma possono anche essere espressioni più complesse.

Combinando jobs -p e kill , possiamo eliminare tutti i processi figli spawnati della shell all'uscita:

trap 'jobs -p | xargs kill' EXIT

reagire al cambiamento della dimensione della finestra dei terminali

C'è un segnale WINCH (WINdowCHange), che viene attivato quando si ridimensiona una finestra di terminale.

declare -x rows cols
 
update_size(){
  rows=$(tput lines) # get actual lines of term
  cols=$(tput cols)  # get actual columns of term
  echo DEBUG terminal window has no $rows lines and is $cols characters wide
}

trap update_size WINCH


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow