2024-10-03 - better error handling in bash

when wiring bash scripts i always use set -eu -o pipefail to make sure any error that's not explicitly handled is a hard fault. sometimes it's however hard to find the exact line, thus i usually just preemptively add set -x at the beginning, so that in case sth fails, i have a full context. it works, but it's clearly ugly.

there's however a much nicer way of handling it – with traps.

let's take a sample starting code:

#!/bin/bash
set -eu -o pipefail
 
echo "hello, world"
date
false "this is where we'll fail"
echo "never see me"

the output is enigmatic:

hello, world
Thu Oct  3 20:30:05 CEST 2024

we never made it to the end. in shell $? is 1, so the error is reported, but in a longer script – good luck finding what exactly failed!

here's how to do this in a better way:

#!/bin/bash
set -eu -o pipefail
 
on_error() {
  echo "ERROR: $0:$BASH_LINENO failed with exit code $? on:" >&2
  echo "  $BASH_COMMAND" >&2
}
 
trap on_error ERR
 
# actual script goes here - same as before:
echo "hello, world"
date
false "this is where we'll fail"
echo "never see me"

and now the output is decodable, indeed:

hello, world
Thu Oct  3 20:32:03 CEST 2024
ERROR: ./my_script:14 failed with exit code 1 on:
  false "this is where we'll fail"

now we get both nice output and a foot in the door, when things fail. it's such a nice, simple feature – no idea why it's not a common thing all over the place.

blog/2024/10/03/2024-10-03_-_better_error_handling_in_bash.txt · Last modified: 2024/10/03 18:34 by basz
Back to top
Valid CSS Driven by DokuWiki Recent changes RSS feed Valid XHTML 1.0