I have a back trace function in bash that works well enough (code below) but the problem is that bash itself when it hits an error, it doesn't give a back trace or any kind of info that would help determine the caller, which can help in debugging the issue.
e.g.:
./c.sh: line 23: urgh: command not found
function backtrace () {
local deptn=${#FUNCNAME[@]}
for ((i=1; i<$deptn; i++)); do
local func="${FUNCNAME[$i]}"
local line="${BASH_LINENO[$((i-1))]}"
local src="${BASH_SOURCE[$((i-1))]}"
printf '%*s' $i '' # indent
echo "at: $func(), $src, line $line"
done
}
Is it possible to trap bash on such errors so I could call my own function to get output like this?
at: c(), ./c.sh, line 22
at: b(), ./c.sh, line 11
at: main(), ./b.sh, line 5
Update: final working version from suggestions and traceback trap on error:
function backtrace () {
local deptn=${#FUNCNAME[@]}
for ((i=1; i<$deptn; i++)); do
local func="${FUNCNAME[$i]}"
local line="${BASH_LINENO[$((i-1))]}"
local src="${BASH_SOURCE[$((i-1))]}"
printf '%*s' $i '' # indent
echo "at: $func(), $src, line $line"
done
}
function trace_top_caller () {
local func="${FUNCNAME[1]}"
local line="${BASH_LINENO[0]}"
local src="${BASH_SOURCE[0]}"
echo " called from: $func(), $src, line $line"
}
set -o errtrace
trap 'trace_top_caller' ERR
Absolutely -- this is exactly what error traps are for:
trap backtrace ERR
In the past, I vaguely recall finding it necessary to make that something more like trap 'backtrace "${#BASH_SOURCE[@]}" "${BASH_SOURCE[@]}" "${#BASH_LINENO[@]}" "${BASH_LINENO[@]}"' ERR
to work around a bug (and reading array values off the function's argv); however, I don't remember at present just what that bug would be and which versions it impacted.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With