
Two simple tricks for better shell script error handling - liraz
http://www.turnkeylinux.org/blog/shell-error-handling
======
guns
(posted to blog comments as well)

If you decide to trap INT or TERM, it would be wise to properly kill your
process with INT or TERM:

    
    
        # if you're using bash, you can use $BASHPID in place of $$
        for sig in INT TERM EXIT; do
            trap "rm -f \"\$TMPFILE\"; [[ $sig == EXIT ]] || kill -$sig $$" $sig
        done
    

Not propagating signals in this manner is being a bad Unix citizen. Bash would
have re-raised the SIGNAL, so you should too.

For more information: <http://www.cons.org/cracauer/sigint.html>

~~~
liraz
I haven't run into any problems (yet) obstructing signal propagation in my
scripts but as you point out it's not The Correct Thing To Do. For the sake of
correctness I'll be updating my error handling code. I find doing the correct
thing often saves me from debugging strange edge cases.

(replied to on blog comments as well)

------
ableal
Personally, I think shell scripts should start with "#! /bin/sh", not going
for some specific shell. If I need more than the standard Bourne shell, I
should probably be using something else.

More or less sane systems have something like this (Ubuntu 9.10):

    
    
        $ ls -l /bin/*sh
        -rwxr-xr-x 1 root root 917960 2009-09-14 06:08 /bin/bash
        -rwxr-xr-x 1 root root 101608 2009-09-21 00:49 /bin/dash
        lrwxrwxrwx 1 root root      4 2009-10-29 19:25 /bin/rbash -> bash
        lrwxrwxrwx 1 root root      4 2009-05-17 19:57 /bin/sh -> dash

~~~
liraz
I find using specific shebangs is a good habit if you don't know exactly which
generic POSIX shell features/syntax you can rely on. In years past I would all
too often use #!/bin/sh for the shebang only to find out later I had
accidentally used a BASH specific shell feature, which is fine if /bin/sh
happens to point to /bin/bash but can break if it points to something else.

OTOH, I believe the error handling tricks discussed should work with any POSIX
shell so I've updated the shebang line in the code snippets to use the more
generic #!/bin/sh.

~~~
KC8ZKF
When invoked as sh, Bash enters POSIX mode after reading the startup files.

~~~
imurray
When invoked that way it still supports more than /bin/dash on my system:

    
    
      % ln -s /bin/bash sh
      % ./sh
      sh-3.2$ echo {1..10}
      1 2 3 4 5 6 7 8 9 10
      sh-3.2$ exit
      % dash
      $ echo {1..10}
      {1..10}
    

where dash is supposed to be POSIX compliant.

------
jcmhn
If your script is a daemon, a runlevel or service script, an at or cron job,
or just needs to spawn or control processes then trap will make you hate unix
and your life.

------
d_r
Another invaluable mention would be "set -u" which triggers an error on
undeclared variables.

