我正在尝试在 bash 脚本中实现一个中止函数,目前看起来像这样:
function abort {
LOGFILE=/var/log/bash_test
DATE=$(date "+%Y %b %a %H:%M:%S")
printf "n------| ERROR: %s line %03d in %s |------n" "$DATE" "$2" "${0}" >> "$LOGFILE"
echo "$1" >> "$LOGFILE"
}
abort "Some kind of error..." $LINENO
这将在/var/log/bash_test 中生成此内容
------| ERROR: 2014 Jan Tue 12:50:12 line 007 in /home/user/test.sh |------
Some kind of error
我的问题是:手动给出行号的方法(例如 2 <$LINENO 美元)是丑陋和重复的。有没有办法让这个函数自动检测函数外部的$LINENO?这样我就可以给出命令
abort "Some kind of error..."
并且仍然得到行号?
您应该能够使用BASH_LINENO:
$ cat test.sh
my_environment() {
echo "Stack size: ${#BASH_LINENO[@]}"
echo "Caller line: ${BASH_LINENO[$((${#BASH_LINENO[@]} - 2))]}"
}
my_environment
$ sh test.sh
Stack size: 2
Caller line: 5
也就是说,倒数第二个条目将是呼叫my_environment
的线路号。
从man bash
部分关于BASH_LINENO
:
一个数组变量,其成员是源文件中的行号,其中调用了 FUNCNAME 的每个相应成员。 ${BASH_LINENO[$i]} 是源文件 (${BASH_SOURCE[$i+1]}) 中的行号,其中调用了 ${FUNCNAME[$i]}(如果在另一个 shell 函数中引用,则调用 ${BASH_LINENO[$i-1]})。 使用 LINENO 获取当前行号。
使用awk,您可以获取行号。以下命令将首先搜索关键字"错误",然后导出行号。
awk '/ERROR/{print NR}' logfile