How to handle error from your bash workflow ?

Introduction

Firstly bash is a powerful programming language to manage external process. After all that is the job to a command line interpreter!

Often i see perl script which use mainly system function. That is a nonsense, take the script change .pl to .sh, remove system and you have mostly a bash script.

The problem

Most of people think to know bash but finally they do not know it well. Is so easy to run a command in bash …

How to handle errors?

That is the job to trap ! trap is a built-in really powerful for this purpose

# die
# This function is used to raise an error
# Parameters:
# - line number
# - message
# - exit code (optional)
die () {
    local parent_lineno message code
      parent_lineno="$1"
      message="$2"
      [[ -n $3 ]] && code="$3" || code=1
      if [[ -n "$message" ]] ; then
        echo "Error on or near line ${parent_lineno}: ${message}; exiting with status ${code}" >&2
      else
        echo "Error on or near line ${parent_lineno}; exiting with status ${code}" >&2
      fi
      end "${code}"
}
## MAIN
trap 'die ${LINENO}'  1 15 ERR
ls $RANDOM
echo 'I am here'

What we do:

  • at line 6-19 we declare the die function
  • at line 21 we tell to bash to call die function if process exit with a signal ERR, 1 or 15
  • at line 22 we try to list a file who has the name given by $RANDOM . I assume this file do not exist
  • line 23 is never call unless you have a file who has the name than the random number given by $RANDOM

Customize the error message

Some time you would like to give a specific message. that is possible, look this

ls $RANDOM || die 'File unknown' 1

If ls fail it will call die function with the specific message and finally script exit with code 1.

Make stronger bash functions

With the same code you can does something close to contract programming.

…
foo(){
    [[ $# -eq 2 ]] || die 'foo function need two parameters: first name, last name'
    [[ -s "$1" ]]  || die 'first name should not to be empty'
    [[ -s "$2" ]]  || die 'last name should not to be empty'
    echo "hello $1 $2"
}

As you can to see using die function with trap built-in will enhance your bash script.

The command built-in

To continue on the same topic they are a built-in little known. That is command. Looking some help for this built-in with your favourite search engine is mostly impossible  as command is too generic keywords.

This built-in will run for you external program and in more :

  • with -v turn on verbose mode, useful for debug
  • with -p parameter it use only default PATH useful to not break a workflow because a lambda user has changed his PATH
  • it will not use alias, you will make safer the script execution. How many people does an alias for ls, grep … and other common tool ?

As you can to understand the built-in command will make your script safer.

Share Button

2 comments

Leave a Reply