Bash Script: catching errors in a block of statements

9,391

You could use the trap shell builtin command to have a handler function called if a command has a non-zero exit status. You can pass necessary information, like the line number and the exit status to your error handler function.

Example:

#!/bin/bash

handle_error() {
    echo "FAILED: line $1, exit code $2"
    exit 1
}

trap 'handle_error $LINENO $?' ERR 

# your commands here
# ...

echo "OK"
Share:
9,391

Related videos on Youtube

Miles Stevenson
Author by

Miles Stevenson

Updated on September 18, 2022

Comments

  • Miles Stevenson
    Miles Stevenson almost 2 years

    I have a large iptables ruleset that I manage with my own bash script. Most of the commands in the script are simple, single-statment iptables commands. I am trying to improve the script by adding success/failure output as the script executes.

    I have the script broken out into different sections. One example would be the FORWARD chain section, where all the rules are applied to the FORWARD chain. At the beginning of the section, I output that the script has started applying the FORWARD rules, and at the end, I want to output whether or not all the rules were applied successfully, or if any of them didn't work. Here is the basic idea:

    #Start FORWARD section
    echo -ne "Applying FORWARD rules..."
    
    #rule 1
    /sbin/iptables -A FOWRARD...
    
    #rule 2
    /sbin/iptables -A FORWARD...
    
    echo -ne "\t\t\t[OK]\n"
    

    What I'm wanting to do is catch any output or errors that may result from each iptables command and store them in an array or something. Then at the end of the block, use an if statement to evaluate the array to see if there were any errors. If not, output the [OK] status, if there were, output the [FAILED] status and display the related error.

    Is there a way I can do this for the entire block of rules without wrapping each iptables rule in an if [ $? != 0 ] expression?

    • Thomas Ward
      Thomas Ward almost 13 years
      This seems like it's better fit for Unix&Linux, or StackOverflow, due to its Linux-related nature, but not Ubuntu-related nature.
    • Lekensteyn
      Lekensteyn almost 13 years
      If your rules are static or can be grouped, consider iptables-apply as it will not apply the rules if one of them fails.
    • DopeGhoti
      DopeGhoti about 8 years
      You could use a trap .. ERR to catch any errors and report on them, or even set -e to abort the script if any uncaught errors are encountered.
  • geirha
    geirha almost 13 years
    Don't test $? for true or false, just run the command in the if in the first place. if ! error=$("$@" ...); then .... Oh and you have a comma in the local command.
  • Michael Gundlach
    Michael Gundlach almost 13 years
    In all my years of bash I've never heard of the trap command!
  • geirha
    geirha almost 13 years
    Sure you can, if checks the return value of the command you run, not whether it outputs anything to stderr.
  • ShadowRunner
    ShadowRunner almost 10 years
    you may have also to : set -o errtrace at the top-level of the script, if you also want that script's functions to call that trap in case of errors (otherwise, inside functions, that trap would not be called)