It’s simple to detect when a shell script begins, nevertheless it’s not all the time simple to know when it stops. A script would possibly finish usually, simply as its writer intends it to finish, nevertheless it may additionally fail resulting from an surprising deadly error. Sometimes it is useful to protect the remnants of no matter was in progress when a script failed, and different occasions it is inconvenient. Either approach, detecting the tip of a script and reacting to it in some pre-calculated method is why the Bash entice
directive exists.
Responding to failure
Here’s an instance of how one failure in a script can result in future failures. Say you’ve got written a program that creates a short lived listing in /tmp
in order that it will probably unarchive and course of recordsdata earlier than bundling them again collectively in a unique format:
#!/usr/bin/env bash
CWD=`pwd`
TMP=$TMP:-/tmp/tmpdir## create tmp dir
mkdir $TMP## extract recordsdata to tmp
tar xf "$1" --directory $TMP## transfer to tmpdir and run instructions
pushd $TMP
for IMG in *.jpg; do
mogrify -verbose -flip -flop $IMG
accomplished
tar --create --file "$".tar *.jpg## transfer again to origin
popd## bundle with bzip2
bzip2 --compress $TMP/"$".tar
--stdout > "$".tbz## clear up
/usr/bin/rm -r /tmp/tmpdir
Most of the time, the script works as anticipated. However, if you happen to by accident run it on an archive crammed with PNG recordsdata as an alternative of the anticipated JPEG recordsdata, it fails midway by way of. One failure results in one other, and finally, the script exits with out reaching its closing directive to take away the momentary listing. As lengthy as you manually take away the listing, you may get well rapidly, however if you happen to aren’t round to try this, then the subsequent time the script runs, it has to cope with an present momentary listing filled with unpredictable leftover recordsdata.
One strategy to fight that is to reverse and double-up on the logic by including a precautionary removing to the beginning of the script. While legitimate, that depends on brute pressure as an alternative of construction. A extra elegant answer is entice
.
Catching indicators with entice
The entice
key phrase catches indicators that will occur throughout execution. You’ve used considered one of these indicators if you happen to’ve ever used the kill
or killall
instructions, which name SIGTERM
by default. There are many different indicators that shells reply to, and you may see most of them with entice --list
:
$ entice --list
1) SIGHUP 2) SIGINT three) SIGQUIT four) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS eight) 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+three
38) SIGRTMIN+four 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+eight
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-eight 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-four 61) SIGRTMAX-three 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
Any of those indicators could also be anticipated with entice
. In addition to those, entice
acknowledges:
EXIT
: Occurs when a course of exitsERR
: Occurs when a course of exits with a non-zero standingDEBUG
: A Boolean representing debug mode
To set a entice in Bash, use entice
adopted by a listing of instructions you need to be executed, adopted by a listing of indicators to set off it.
For occasion, this entice detects a SIGINT
, the sign despatched when a person presses Ctrl+C whereas a course of is operating:
entice " echo 'Terminated with Ctrl+C'; " SIGINT
The instance script with momentary listing issues may be mounted with a entice detecting SIGINT
, errors, and profitable exits:
#!/usr/bin/env bash
CWD=`pwd`
TMP=$TMP:-/tmp/tmpdirentice
" /usr/bin/rm -r $TMP ; exit 255; "
SIGINT SIGTERM ERR EXIT## create tmp dir
mkdir $TMP
tar xf "$1" --directory $TMP## transfer to tmp and run instructions
pushd $TMP
for IMG in *.jpg; do
mogrify -verbose -flip -flop $IMG
accomplished
tar --create --file "$".tar *.jpgh## transfer again to origin
popd## zip tar
bzip2 --compress $TMP/"$".tar
--stdout > "$".tbz
For advanced actions, you may simplify entice
statements with Bash functions.
Traps in Bash
Traps are helpful to make sure that your scripts finish cleanly, whether or not they run efficiently or not. It’s by no means protected to rely fully on automated rubbish assortment, so this can be a good behavior to get into on the whole. Try utilizing them in your scripts, and see what they will do!