spi*_*zak 14 bash scripting logging
我正试图找到一种方法来找出调用函数的文件和行号.该函数位于库文件中,该文件由我的脚本提供.
文件1:
$source file2
$warn_me "Error: You didn't do something"
Run Code Online (Sandbox Code Playgroud)
文件2:
$function warn_me() {
$ message=????
$ echo ${message}
$}
Run Code Online (Sandbox Code Playgroud)
期望的输出: $:file1:第2行:错误:你没有做任何事情
函数调用已经在很多文件中多次出现,所以我试图找到一种方法来做到这一点而不改变它.
以前warn_me函数是在每个使用它的文件中定义的,并且这样做是这样的:
$local message="$BASH_SOURCE:(""${BASH_LINENO}): ""$*"
Run Code Online (Sandbox Code Playgroud)
Wri*_*ken 14
你正在寻找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
Run Code Online (Sandbox Code Playgroud)
受@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}"
}
Run Code Online (Sandbox Code Playgroud)
更新:我修复了拼写错误并添加了错误消息参数.因此,该函数的第一个参数是要添加到堆栈跟踪的错误消息.顺便说一句,如果您的脚本是在bash
stdin 上提供的(在大多数情况下是个坏主意),那么第一个位置就会丢失.如果需要,然后在for
循环中,将其更改为i<$stack_size + 1
.但正如我所说,将你的脚本提供给bash的stdin并不是一个好主意,这就是原因.
更新2:我发现我对此有一个较旧的答案.想更好地将代码的更新版本保存在一个地方.所以决定做一个要点.随意建议改进要点.如果发生任何变化,我会尝试更新此答案,但我不能保证.