I greatly benefit from having a stack traceback in my bash scripts. However, there was always the periodic glitch that I just ignored until I took the time today to make a minimal working example:
#!/bin/bash # 1
set -o errexit # 2
set -o errtrace # 3
trap 'stacktrace' ERR # 4
function bad(){ # 5
return 1; } # 6
function good(){ bad; } # 7
function stacktrace(){ # 8
echo "Lines = ${BASH_LINENO[*]}" # 9
echo "Funcs = ${FUNCNAME[*]}" #10
} #11
function mymain(){ #12
good #13
} #14
echo "$BASH_VERSION" #15
mymain #16
# call tree:
#-------------
# mymain
# good
# bad
# return 1
#-------------------
# output is:
#-------------------
# 4.3.46(1)-release
# Lines = 6 13 16 0
# Funcs = stacktrace good mymain main
I kinda would have expected that the error trap would have been triggered on line 7 when bad() returns an error code, but OK, bash has its many little ways. The real problem is, I can't see enough information here to give a correct stack traceback. Line #7 in function good() must surely be part of the stack traceback for this error, no matter how you cut it.
I can imagine some really nasty workaround for this, but hopefully I'm missing something and someone can point out how to correctly identify line #7 as part of the stack traceback in this situation.
My fear is that this is unfortunate bash behavior, that it has popped bad() from the stack before triggering the trap but also before popping the current line# to the caller (line #7), effectively ending up reporting that line #6 belongs to good() rather than to bad().