I want to have a cleanup action in my Bash scripts, like this:
#! /bin/bash
set -eu
trap 'echo "E: failed with exitcode $?" 1>&2' ERR
true
false
Using $?
came to mind as a natural choice, but this isn't the case. It always contains 0
. Is there any way that I can "spy" on the exitcode in the ERR
trap?
[Update:] I have no idea what I had tested before. This code works like a charm, so I'm leaving it here as a small and good example.
Your (probably simplified) example doesn't exhibit the problem you've mentioned:
+ set -eu
+ trap 'echo "E: failed with exitcode $?" 1>&2' ERR
+ true
+ false
++ echo 'E: failed with exitcode 1'
E: failed with exitcode 1
Chances are that the command returning ERR
is executed in a &&
or ||
, or subject to other conditions mentioned in the snippet below. Quoting from the manual:
If a sigspec is ERR
, the command arg is executed whenever a simple
command has a non-zero exit status, subject to the following
conditions. The ERR
trap is not executed if the failed command is part
of the command list immediately following an until
or while
keyword,
part of the test following the if
or elif
reserved words, part of a
command executed in a &&
or ||
list, or if the command’s return status
is being inverted using !
. These are the same conditions obeyed by the
errexit
option.
So if you have, for example, the following:
#! /bin/bash
set -eu
trap 'echo "E: failed with exitcode $?" 1>&2' ERR
false && true
Executed it wouldn't cause the failure to be trapped:
+ set -eu
+ trap 'echo "E: failed with exitcode $?" 1>&2' ERR
+ false