I'm working on a bash script and as I've been going I've learned about traps, signals, function return codes and other such features I've not previously used.

I may be thinking about things incorrectly - I'm looking for some advice.

I am setting the following options:

set -o errexit
set -o nounset
set -o noclobber

I've got the following exit and err traps in my bash script:

# Error handler. This function is called anytime an ERR signal is received.
# This function should never be explictly called.
function _trap_error () {
    if [ ! -v _VERBOSE ]; then
        echo "An error has occurred. Exiting."
        _name="$0"                # name of the script
        _lastline="$1"            # argument 1: last line of error occurence
        _lasterr="$2"             # argument 2: error code of last command
        echo "${_name}: line ${_lastline}: exit status of last command: ${_lasterr}"
        exit 1
trap '_trap_error ${LINENO} ${$?}' ERR

# Exit handler. This function is called anytime an EXIT signal is received.
# This function should never be explicitly called.
function _trap_exit () {
    [ -v _POPD ] && popd &> /dev/null
trap _trap_exit EXIT

They work much as I'd expect. Rather than inserting error checking into all my functions, I'm attempting to leverage the traps to handle this for me, for example when checking for the existence of a file. If the specified module can't be loaded, I'd like to catch it as an error, display an error message, and exit.

function _module_path () {
    echo "mod.d/$2s/$1/__init__.sh"

function _module_exists () {
    [ -f $(_module_path $1 $2) ] && return 0 || return 1

function _module_push () {
    _module_exists $1 $2 && _MODULES+=$( _module_path $1 $2 ) || msg "Module $1 does not exist."

However, setting the return code to 0 in conjunction with errexit triggers an EXIT signal, which is caught by my exit trap instead. I started trying to figure out if I can manually emit an ERR signal instead, but haven't found an answer and started to wonder if I'm going about this correctly.

closed as unclear what you're asking by Gilles, slm, devnull, Anthon, strugee Apr 21 '14 at 17:27

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • Please look at the following answer, especially if you're using [ -v ]. I think its the best answer I've ever written. Also, what is ${$?} ? I suspect it's your problem. That should be an invalid substitution as far as I can tell. unix.stackexchange.com/a/120008/52934 – mikeserv Apr 20 '14 at 1:21
  • From info bash: The ERR trap is not executed if the failed command is part of the command list immediately following a while or until keyword, part of the test in an if statement, part of a command executed in a && or || list, or if the command's return value is being inverted via !. – devnull Apr 20 '14 at 2:55
  • @devnull That's true too - traps are triggered for otherwise unhandled exceptions. A while or until wouldn't trigger as they are explicit tests. While loops don't return a failure code just because their defined parameters run out. But if you want an error code all you have to do is ${unset_var?this is written to stderr} or just false – mikeserv Apr 20 '14 at 3:05
  • @mikeserv "$?" is the error code of the last executed command. – nfarrar Apr 20 '14 at 15:31
  • 1
    Im well aware of that. I just checked and it seems to work, but it is strange. For instance, echo ${$?} works, but n=$? ; echo ${$n} returns a bad substitution error. See what i mean? Don't know why youre putting ${} around it. Please see that other post - it discusses all kinds of ways of generating, handling errors. – mikeserv Apr 20 '14 at 16:13