Science and technology

Using Bash traps in your scripts

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 exits
  • ERR: Occurs when a course of exits with a non-zero standing
  • DEBUG: 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/tmpdir

entice
 " /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!

Most Popular

To Top