Quando uso il comando "trap" in bash, il trap precedente per il segnale specificato viene sostituito.più trappole bash per lo stesso segnale
C'è un modo per fare più di un fuoco di trappola per lo stesso segnale?
Quando uso il comando "trap" in bash, il trap precedente per il segnale specificato viene sostituito.più trappole bash per lo stesso segnale
C'è un modo per fare più di un fuoco di trappola per lo stesso segnale?
Edit:
Sembra che ho letto male la domanda. La risposta è semplice:
handler1() { do_something; }
handler2() { do_something_else; }
handler3() { handler1; handler2; }
trap handler3 SIGNAL1 SIGNAL2 ...
originale:
Basta elencare più segnali alla fine del comando:
trap function-name SIGNAL1 SIGNAL2 SIGNAL3 ...
È possibile trovare la funzione associata a un particolare segnale utilizzando trap -p
:
trap -p SIGINT
Nota che elenca ciascun segnale separatamente anche se sono gestiti dalla stessa funzione.
è possibile aggiungere un ulteriore segnale dato un una nota in questo modo:
eval "$(trap -p SIGUSR1) SIGUSR2"
Questo funziona anche se ci sono altri segnali aggiuntivi in fase di elaborazione da parte della stessa funzione. In altre parole, diciamo che una funzione stava già gestendo tre segnali: si potevano aggiungere altri due semplicemente facendo riferimento a uno esistente e aggiungendone altri due (in cui solo uno è mostrato sopra solo all'interno delle virgolette di chiusura).
Se si utilizza Bash> = 3.2, è possibile eseguire un'operazione come questa per estrarre la funzione in base a un segnale. Si noti che non è completamente robusto perché potrebbero apparire altre virgolette singole.
[[ $(trap -p SIGUSR1) =~ trap\ --\ \'([^\047])\'.* ]]
function_name=${BASH_REMATCH[1]}
Quindi è possibile ricostruire il comando trap da zero se è necessario utilizzare il nome della funzione, ecc.
ha chiesto per molteplici trappole per lo stesso segnale, non è la stessa trappola per multiple segnali. – Darron
@Darron: Siamo spiacenti, ho letto male la domanda. La risposta alla domanda ** effettiva ** è molto più semplice e l'ho aggiunta in alto. –
stai ancora sparando solo una trappola - che la trappola in questione invoca più funzioni e raggiunge l'effetto è più o meno indiscutibile. L'unica ragione per cui potrebbero esserci motivi di contestazione è che se handler1 è installato per primo, ed è progettato per uscire, quindi handler2 non verrà attivato. Ma c'è ancora solo una azione sparata. (Sei sempre stato in grado di avere una sequenza arbitrariamente complessa di operazioni nell'azione innescata.) –
Circa il meglio che si possa fare è eseguire più comandi da una singola trap
per un dato segnale, ma non è possibile avere più trappole simultanei per un singolo segnale. Ad esempio:
$ trap "rm -f /tmp/xyz; exit 1" 2
$ trap
trap -- 'rm -f /tmp/xyz; exit 1' INT
$ trap 2
$ trap
$
La prima riga imposta un trap sul segnale 2 (SIGINT). La seconda riga stampa le trap correnti: dovresti catturare l'output standard da questo e analizzarlo per il segnale che desideri. Quindi, puoi aggiungere il tuo codice a ciò che era già lì - notando che il codice precedente probabilmente include un'operazione di "uscita". La terza invocazione di trap cancella la trappola su 2/INT. L'ultimo mostra che non ci sono trappole in sospeso.
È anche possibile utilizzare trap -p INT
o trap -p 2
per stampare il trap per un segnale specifico.
Tecnicamente non è possibile impostare più trappole per lo stesso segnale, ma è possibile aggiungere a una trappola esistente:
trap -p
Ecco una funzione bash che fa quanto sopra:
# note: printf is used instead of echo to avoid backslash
# processing and to properly handle values that begin with a '-'.
log() { printf '%s\n' "$*"; }
error() { log "ERROR: $*" >&2; }
fatal() { error "[email protected]"; exit 1; }
# appends a command to a trap
#
# - 1st arg: code to add
# - remaining args: names of traps to modify
#
trap_add() {
trap_add_cmd=$1; shift || fatal "${FUNCNAME} usage error"
for trap_add_name in "[email protected]"; do
trap -- "$(
# helper fn to get existing trap command from output
# of trap -p
extract_trap_cmd() { printf '%s\n' "$3"; }
# print existing trap command with newline
eval "extract_trap_cmd $(trap -p "${trap_add_name}")"
# print the new trap command
printf '%s\n' "${trap_add_cmd}"
)" "${trap_add_name}" \
|| fatal "unable to add to trap ${trap_add_name}"
done
}
# set the trace attribute for the above function. this is
# required to modify DEBUG or RETURN traps because functions don't
# inherit them unless the trace attribute is set
declare -f -t trap_add
Esempio di utilizzo:
trap_add 'echo "in trap DEBUG"' DEBUG
Questa è più direttamente una risposta a http://stackoverflow.com/q/16115144/754997 –
Ecco un'altra opzione:
on_exit_acc() {
local next="$1"
eval "on_exit() {
local oldcmd='$(echo "$next" | sed -e s/\'/\'\\\\\'\'/g)'
local newcmd=\"\$oldcmd; \$1\"
trap -- \"\$newcmd\" 0
on_exit_acc \"\$newcmd\"
}"
}
on_exit_acc true
Usage:
$ on_exit date
$ on_exit 'echo "Goodbye from '\''`uname`'\''!"'
$ exit
exit
Sat Jan 18 18:31:49 PST 2014
Goodbye from 'FreeBSD'!
tap#
mi è piaciuta la risposta di Richard Hansen, ma non mi interessa per Embedded funziona in modo alternato è:
#===================================================================
# FUNCTION trap_add()
#
# Purpose: appends a command to a trap
#
# - 1st arg: code to add
# - remaining args: names of traps to modify
#
# Example: trap_add 'echo "in trap DEBUG"' DEBUG
#
# See: http://stackoverflow.com/questions/3338030/multiple-bash-traps-for-the-same-signal
#===================================================================
trap_add() {
trap_add_cmd=$1; shift || fatal "${FUNCNAME} usage error"
new_cmd=
for trap_add_name in "[email protected]"; do
# Grab the currently defined trap commands for this trap
existing_cmd=`trap -p "${trap_add_name}" | awk -F"'" '{print $2}'`
# Define default command
[ -z "${existing_cmd}" ] && existing_cmd="echo exiting @ `date`"
# Generate the new command
new_cmd="${existing_cmd};${trap_add_cmd}"
# Assign the test
trap "${new_cmd}" "${trap_add_name}" || \
fatal "unable to add to trap ${trap_add_name}"
done
}
Non mi piace dover giocare con queste manipolazioni di stringhe che sono fonte di confusione il più delle volte, quindi mi si avvicinò con qualcosa di simile:
(ovviamente è possibile modificarlo per altri segnali)
exit_trap_command=""
function cleanup {
eval "$exit_trap_command"
}
trap cleanup EXIT
function add_exit_trap {
local to_add=$1
if [[ -z "$exit_trap_command" ]]
then
exit_trap_command="$to_add"
else
exit_trap_command="$exit_trap_command; $to_add"
fi
}
mi sono imbattuto in un problema simile e si avvicinò con [questo] (http://stackoverflow.com/a/16115145/1449569) –