Zoeken…


Syntaxis

  • trap action sigspec ... # Voer "action" uit op een lijst met signalen
  • trap sigspec ... # Als actie wordt weggelaten, worden vallen voor signalen opnieuw ingesteld

parameters

Parameter Betekenis
-p Lijst met momenteel geïnstalleerde vallen
l Lijst met signaalnamen en bijbehorende nummers

Opmerkingen

Het trap is een speciale ingebouwde shell. Het is gedefinieerd in POSIX , maar bash voegt ook enkele nuttige extensies toe.

Voorbeelden die POSIX-compatibel zijn, beginnen met #!/bin/sh en voorbeelden die beginnen met #!/bin/bash gebruiken een bash-extensie.

De signalen kunnen een signaalnummer, een signaalnaam (zonder het SIG-voorvoegsel) of het speciale trefwoord EXIT .

Die gegarandeerd door POSIX zijn:

Aantal Naam Notes
0 UITGANG Voer altijd shell-exit uit, ongeacht de exit-code
1 SIGHUP
2 SIGINT Dit is wat ... ^C stuurt
3 SIGQUIT
6 SIGABRT
9 SIGKILL
14 SIGALRM
15 SIGTERM Dit is wat kill standaard verzendt

SIGINT of Ctl + C vangen

De val wordt opnieuw ingesteld voor subshells, dus de sleep zal nog steeds werken op het SIGINT signaal verzonden door ^C (meestal door te stoppen), maar het bovenliggende proces (dwz het shellscript) niet.

#!/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

En een variant waarmee u nog steeds het hoofdprogramma kunt afsluiten door tweemaal in een seconde op ^C drukken:

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

Inleiding: tijdelijke bestanden opschonen

U kunt het trap commando gebruiken om signalen te "vangen"; dit is het shell-equivalent van de sigaction() van signal() of sigaction() in C en de meeste andere programmeertalen om signalen op te vangen.

Een van de meest voorkomende toepassingen van trap is het opschonen van tijdelijke bestanden bij zowel een verwachte als een onverwachte exit.

Helaas doen dit niet genoeg shell-scripts :-(

#!/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.

Verzamel een lijst met trapwerkzaamheden die bij uitgang moeten worden uitgevoerd.

Ben je ooit vergeten een trap toe te voegen om een tijdelijk bestand op te schonen of ander werk te doen bij het afsluiten?

Heb je ooit een val gezet die een andere heeft geannuleerd?

Deze code maakt het gemakkelijk om dingen toe te voegen die moeten worden gedaan bij het afsluiten van één item tegelijk, in plaats van ergens een grote trap instructie in uw code te hebben, die misschien gemakkelijk te vergeten is.

# 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
}

Het doden van kindprocessen bij afsluiten

Trap-expressies hoeven geen afzonderlijke functies of programma's te zijn, het kunnen ook complexere expressies zijn.

Door jobs -p en kill combineren, kunnen we alle spawned onderliggende processen van de shell bij het afsluiten doden:

trap 'jobs -p | xargs kill' EXIT

reageren op verandering van de grootte van het terminalvenster

Er is een signaal WINCH (WINdowCHange), dat wordt geactiveerd wanneer het formaat van een terminalvenster wordt gewijzigd.

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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow