You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

额外优化说明

  1. 修复了原代码中[ "$i" -gt "$(sed -n '$=' plist)"]的空格问题(]前必须加空格,否则bash会报错)
  2. 将sed $i'!d'改为sed "$i!d",避免变量展开时出现语法冲突
  3. 用grep -q "$0" plist替代[ "$(cat plist)" == *"$0"* ],减少不必要的文件读取操作
  4. trap命令改用单引号包裹,确保后续npl变量值变化时,trap能获取到最新值

内容的提问来源于stack exchange,提问作者OK9090

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 23:01:23