【问题标题】:Shell script print line number when it errors outShell 脚本在出错时打印行号
【发布时间】:2015-03-16 16:06:16
【问题描述】:

我一直在寻找一种方法来在 shell 脚本出错时打印行号。

我遇到了 '-x' 选项,它在运行 shell 脚本时打印该行,但这并不是我想要的。也许我可以在每个退出代码之前做 $LINENO ?有更清洁的方法吗?

我只想要行号,这样我就可以打开 shell 脚本并直接转到解释器发现错误的地方。

【问题讨论】:

    标签: bash shell scripting


    【解决方案1】:

    使用

    PS4=':$LINENO+'
    

    将在set -x的输出中添加行号。


    如果您想在错误时打印,则存在一些在最近的解释器中遇到错误的风险。但是,您可以尝试以下方法(首先在this previous answer 中给出):

    error() {
      local parent_lineno="$1"
      local message="$2"
      local code="${3:-1}"
      if [[ -n "$message" ]] ; then
        echo "Error on or near line ${parent_lineno}: ${message}; exiting with status ${code}"
      else
        echo "Error on or near line ${parent_lineno}; exiting with status ${code}"
      fi
      exit "${code}"
    }
    trap 'error ${LINENO}' ERR
    

    同样,这在最近的一些 bash 版本中不起作用,它们并不总是在陷阱内正确设置 LINENO


    另一种方法(适用于最近的 shell;下面使用一些 bash 4.0 和 4.1 功能)是使用PS4 将每个命令的退出状态和行号发送到专用文件描述符,并使用tail 仅打印在 shell 退出之前给该 FD 的最后一行:

    exec {BASH_XTRACEFD}> >(tail -n 1) # send set -x output to tail -n 1
    PS4=':At line $LINENO; prior command exit status $?+'
    set -x
    

    【讨论】:

    • 如果这个 shell 脚本因为 bash 版本而失败是有风险的,因为它将在不同的 shell 中重复使用。我想我会选择 PS4=':$LINENO+' 的第一个选项。我真的不想要实际的线条,因为它会使控制台杂乱无章,但如果这是在任何地方都可以使用的安全方式,那就这样吧。
    • 您可以随时查看$BASH_VERSION 并根据结果使用不同的代码。
    • @user2441441, ...或者,如果您不需要 stderr 来处理其他任何事情,那么很容易使最后的代码与旧版本的 bash 一起工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-22
    相关资源
    最近更新 更多