Some err traps are skipped with set e

This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the bash category.

Last Updated: 2024-03-05

I had a shell script as follows:

set -e

# Define the cleanup function before the trap
cleanup() {
  rm -rf workingdir
}

trap 'cleanup' ERR

do_work() {
  mkdir workingdir
  command_that_fails_sporadically
}

do_work

When this script failed randomly, to my confusion, I saw that the workingdir persisted despite my trap.

In turns out that set -e causes the function do_work to immediately leave. There are no traps in that function context, so it leaves without calling any traps.

If I wanted the trap to get called, here are are few alternatives:

  1. Use set -o errexit -o errtrace, or, in short form set -eE

  2. Move the code in do_work outside of a function

set -e

cleanup() {
  rm -rf workingdir
}

trap 'cleanup' ERR

mkdir workingdir
command_that_fails_sporadically

Now it clears the working directoy

  1. Trap EXIT instead of ERR (however this might be too eager since the trap also gets called on successful exit)

Resources