Find line number of function call from sourcing file

耗尽温柔 提交于 2019-12-18 05:42:52

问题


I'm trying to find a way to find out what file and line number a function was called from. The function is in a library file which is being sourced by my script.

file1:

$source file2
$warn_me "Error: You didn't do something"

file2:

$function warn_me() {
$  message=????
$  echo ${message}
$}

Desired Output: $: file1:Line 2: Error: You didn't do something

The function call already occurs many times in many files so I'm trying to find a way to do this without changing that.

Previously the warn_me function was defined in every file that used it and this was taken care of like so:

$local message="$BASH_SOURCE:(""${BASH_LINENO}): ""$*"

回答1:


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



回答2:


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.




回答3:


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


来源:https://stackoverflow.com/questions/11090899/find-line-number-of-function-call-from-sourcing-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!