Find line number of function call from sourcing file
There are three array variables that can be used for this purpose:
FUNCNAME
BASH_SOURCE
BASH_LINENO
See the following answer for more details:
- https://stackoverflow.com/a/10707498/1305501
Inspired by @nosid and @Wrikken I wrote a small function to put current stack trace into a variable called $STACK. It might be useful to output to user the location some error has happened. Too bad bash does not have a built-in printStackTrace... Hope somebody could find it handy in their projects.
function get_stack () {
STACK=""
local i message="${1:-""}"
local stack_size=${#FUNCNAME[@]}
# to avoid noise we start with 1 to skip the get_stack function
for (( i=1; i<$stack_size; i++ )); do
local func="${FUNCNAME[$i]}"
[ x$func = x ] && func=MAIN
local linen="${BASH_LINENO[$(( i - 1 ))]}"
local src="${BASH_SOURCE[$i]}"
[ x"$src" = x ] && src=non_file_source
STACK+=$'\n'" at: "$func" "$src" "$linen
done
STACK="${message}${STACK}"
}
Update: I fixed a typo and added an error message parameter. So first parameter of the function is an error message to be added to the stack trace. btw if your script supplied on bash
's stdin (a bad idea in most cases), then the first position would be lost. If needed, then inthe for
loop, change it to i<$stack_size + 1
. But as I said, it is not good idea to feed your script to bash`s stdin, here's why.
Update 2: I found I have an older answer about this. Thought to better keep updated version of the code in one place. So decided to make a gist. Feel free to suggest improvements to the gist. I'll try to keep this answer updated if any changes occur but I can't guarantee.
You are looking for caller
it seems.
$ cat h.sh
#! /bin/bash
function warn_me() {
echo "$@"
caller
}
$ cat g.sh
#!/bin/bash
source h.sh
warn_me "Error: You didn't do something"
$ . g.sh
Error: You didn't do something
3 g.sh