20

我正在使用set -e在第一个错误时停止执行脚本。

问题是这并没有告诉我出了什么问题。

如何更新 bash 脚本,以便它显示最后一个失败的命令?

4

5 回答 5

22

代替set -e,使用 ERR 陷阱;您可以传入$BASH_LINENO以获取发生错误的特定行号。我在https://stackoverflow.com/a/185900/14122的回答中提供了一个利用这一点的脚本

总结一下:

error() {
   local sourcefile=$1
   local lineno=$2
   # ...logic for reporting an error at line $lineno
   #    of file $sourcefile goes here...
}
trap 'error "${BASH_SOURCE}" "${LINENO}"' ERR
于 2012-05-24T20:04:58.960 回答
5
  1. 制作 err.sh

    set -e
    trap 'echo "ERROR: $BASH_SOURCE:$LINENO $BASH_COMMAND" >&2' ERR
    
  2. 将它 ( . err.sh) 包含在所有脚本中。

  3. 替换任何

    ... | while read X ; do ... ; done

    while read X ; do ... ; done < <( ... )

    在您的脚本中让陷阱在错误消息中提供正确的行号/命令

于 2017-03-15T10:19:42.773 回答
1

你试过--verbose吗?

bash --verbose script.sh
于 2012-05-24T18:17:50.330 回答
1

您不能单独使用set -e,因为处理将在任何错误后立即停止。查看 Bash 参考手册的Set Builtin 部分,了解有关 -x 和 -v 选项的更多信息,您可以使用它们进行调试。

就像是:

set -e
set -v

将在任何错误时退出,同时在读取时向您显示每个输入行。但是,它不会只显示错误所在的行。为此,您需要进行自己的显式错误检查。

例如:

set +e
if false; then
    real_exit_status=$?
    echo 'Some useful error message.' >&2
    exit $real_exit_status
fi
于 2012-05-24T19:39:43.257 回答
0

set -ex将在执行时显示(所有)行,并在第一个返回非零的命令处停止(不作为if/while/until构造的一部分)。

于 2012-05-24T21:02:24.263 回答