如何在Bash函数中获取函数调用行号而非定义行号?
解决DEBUG trap中获取触发行号的问题
在bash的DEBUG trap函数中,$LINENO默认返回的是函数定义内部的行号,要获取触发trap的脚本行号,需要使用特殊变量$BASH_LINENO。
原理说明
当DEBUG trap触发时,bash会维护一个调用栈行号数组BASH_LINENO:
BASH_LINENO[0]对应触发trap的那一行脚本的行号(也就是你需要的函数调用点行号)BASH_LINENO[1]则是trap函数本身被定义的行号,以此类推
修改后的代码
把原代码中step函数里的$LINENO替换为${BASH_LINENO[0]}即可,同时修复了几处语法问题:
getnextp() { i=0 small=$1 execute= while :; do ((i++)) # 修复空格缺失的语法问题 if [ "$i" -gt "$(sed -n '$=' plist)" ]; then break fi line=$(sed "$i!d" plist) if [ "$line" = "$0" ]; then ((i++)) ((i++)) line=$(sed "$i!d" plist) if [ "$line" -lt "$small" ]; then small="$line" ((i--)) line=$(sed "$i!d" plist) execute=$line ((i++)) fi fi done } npl=999999999 step() { echo "Working." # 输出触发trap的脚本行号 echo "${BASH_LINENO[0]}" # 用grep替代cat+通配符,提升效率 if grep -q "$0" plist; then getnextp "$1" # 使用触发行号进行判断 if [ "${BASH_LINENO[0]}" = "$small" ]; then cd ../ ./packages/"$execute" fi fi } # 用单引号包裹trap命令,避免变量提前展开 trap 'step "$npl"' DEBUG
额外优化说明
- 修复了原代码中
[ "$i" -gt "$(sed -n '$=' plist)"]的空格问题(]前必须加空格,否则bash会报错) - 将
sed $i'!d'改为sed "$i!d",避免变量展开时出现语法冲突 - 用
grep -q "$0" plist替代[ "$(cat plist)" == *"$0"* ],减少不必要的文件读取操作 - trap命令改用单引号包裹,确保后续
npl变量值变化时,trap能获取到最新值
内容的提问来源于stack exchange,提问作者OK9090
相关产品推荐
相关产品推荐

