Shell脚本:当出错时打印行号

11

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

我发现了'-x'选项,它可以在运行shell脚本时打印出所在的行,但这并不完全是我想要的。也许我可以在每个退出代码之前使用$LINENO? 有没有更简洁的方法呢?

我只想要行号,这样我就可以打开shell脚本,直接跳转到解释器意识到错误的位置。

1个回答

13

使用

PS4=':$LINENO+'

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


如果您仅仅想在出错时打印行号,那么最近版本的解释器存在一些风险。然而,您可以尝试以下方法(首次提供于此前的回答):

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 退出之前接收到的最后一行:

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 版本问题失败,那么风险很大,因为它将在不同的 shells 中被重复使用。 我认为我会选择 PS4=':$LINENO+' 的第一个选项。我实际上不想要实际的行数,因为它会使控制台混乱,但是如果这是安全可靠的方式,并且可以在任何地方工作,那就这样吧。 - user2441441
你可以随时检查 $BASH_VERSION 并根据结果使用不同的代码。 - Charles Duffy
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Charles Duffy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接