从源文件中查找函数调用的行号

时间:2012-06-18 20:57:37

标签: bash logging scripting

我正试图找到一种方法来找出调用函数的文件和行号。该函数位于库文件中,该文件由我的脚本提供。

文件1:

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

file2的:

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

所需的输出: $:file1:第2行:错误:您没有做某事

函数调用已经在很多文件中多次出现,所以我试图找到一种方法来做到这一点而不改变它。

以前warn_me函数是在每个使用它的文件中定义的,并且这样做是这样的:

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

3 个答案:

答案 0 :(得分:13)

您正在寻找caller

$ 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

答案 1 :(得分:7)

有三个数组变量可用于此目的:

  • FUNCNAME
  • BASH_SOURCE
  • BASH_LINENO

有关详细信息,请参阅以下答案:

答案 2 :(得分:7)

受@nosid和@Wrikken的启发我编写了一个小函数,将当前堆栈跟踪放入一个名为$ STACK的变量中。向用户输出发生错误的位置可能很有用。太糟糕的bash没有内置的printStackTrace ......希望有人能在他们的项目中找到它。

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}"
}

更新:我修正了拼写错误并添加了错误消息参数。因此,该函数的第一个参数是要添加到堆栈跟踪的错误消息。顺便说一句,如果你的脚本在bash的stdin上提供(在大多数情况下是个坏主意),那么第一个位置就会丢失。如果需要,则在for循环中将其更改为i<$stack_size + 1。但正如我所说,将你的脚本提供给bash`s stdin here's why并不是一个好主意。

更新2:我发现我有一个older answer。想更好地将代码的更新版本保存在一个地方。因此决定制作一个gist。随意建议改进要点。如果发生任何变化,我会尝试更新此答案,但我不能保证。