Print a stack trace on error
Print the call chain on a failure with an ERR trap that walks the FUNCNAME, BASH_SOURCE and BASH_LINENO arrays, innermost function first.
An error three functions deep reports only its own line, and you want the path the script took to get there.
set -eE
trap 'rc=$?; echo "error $rc in: $BASH_COMMAND" >&2
for ((i = 0; i < ${#FUNCNAME[@]} - 1; i++)); do
echo " at ${FUNCNAME[i]} (called from ${BASH_SOURCE[i+1]}:${BASH_LINENO[i]})" >&2
done' ERR
inner() { false; }
middle() { inner; }
outer() { middle; }
outererror 1 in: false
at inner (called from main.sh:7)
at middle (called from main.sh:8)
at outer (called from main.sh:9)Bash keeps the call stack in three parallel arrays: FUNCNAME has the function names with the innermost first, BASH_LINENO[i] is the line from which FUNCNAME[i] was called, and BASH_SOURCE[i+1] is the file that line is in. Inside an ERR trap those arrays still describe the failing context, so the loop prints one line per function frame. The arrays are documented in the Bash manual.
Define the trap before the functions that may fail, and keep -E so it also fires inside them. The trap can run more than once as the failure propagates through each frame under set -e. The arrays are empty for a command typed at the prompt and for bash -c, so BASH_SOURCE has no file name there. caller prints one frame at a time.