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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11090899/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 02:31:32  来源:igfitidea点击:

Find line number of function call from sourcing file

bashloggingscripting

提问by spizzak

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:

文件 1:

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

file2:

文件2:

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

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

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

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:

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

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

回答by Wrikken

You are looking for callerit seems.

你正在寻找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

回答by akostadinov

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.

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

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 forloop, 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.

更新:我修正了一个错字并添加了一个错误消息参数。因此该函数的第一个参数是要添加到堆栈跟踪中的错误消息。顺便说一句,如果您的脚本在bash的标准输入上提供(在大多数情况下是个坏主意),那么第一个位置将丢失。如果需要,然后在for循环中将其更改为i<$stack_size + 1. 但是正如我所说,将脚本提供给 bash 的标准输入并不是一个好主意,这就是为什么.

Update 2: I found I have an older answerabout 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.

更新 2:我发现我对此有一个较旧的答案。想更好地将代码的更新版本保存在一个地方。所以决定做一个要点。随意提出改进要点的建议。如果发生任何更改,我会尝试更新此答案,但我不能保证。

回答by nosid

There are three array variables that can be used for this purpose:

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

  • FUNCNAME
  • BASH_SOURCE
  • BASH_LINENO
  • FUNCNAME
  • BASH_SOURCE
  • BASH_LINENO

See the following answer for more details:

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