在Bash脚本中引发错误
我想在消息“测试用例失败!!!”的Bash脚本中引发错误。 如何在Bash中做到这一点?
例如:
if [ condition ]; then
raise error "Test cases failed !!!"
fi
这取决于您想要存储错误消息的位置。
您可以执行以下操作:
echo "Error!" > logfile.log
exit 125
或者以下:
echo "Error!" 1>&2
exit 64
当你引发异常时,你停止程序的执行。
您也可以使用类似exit xxx
地方,其中xxx
是您可能想要返回到操作系统的错误代码(从0到255)。 这里125
和64
只是随机代码,你可以退出。 当您需要向操作系统表明程序异常停止(例如发生错误)时,您需要传递非零退出代码以exit
。
正如@chepner指出的那样,你可以做exit 1
,这意味着一个未明确的错误。
基本的错误处理
如果你的测试用例运行者为失败的测试返回一个非零代码,你可以简单地写出:
test_handler test_case_x; test_result=$?
if ((test_result != 0)); then
printf '%sn' "Test case x failed" >&2 # write error message to stderr
exit 1 # or exit $test_result
fi
甚至更短:
if ! test_handler test_case_x; then
printf '%sn' "Test case x failed" >&2
exit 1
fi
或者最短的:
test_handler test_case_x || { printf '%sn' "Test case x failed" >&2; exit 1; }
用test_handler的退出码退出:
test_handler test_case_x || { ec=$?; printf '%sn' "Test case x failed" >&2; exit $ec; }
高级错误处理
如果你想采取更全面的方法,你可以有一个错误处理程序:
exit_if_error() {
local exit_code=$1
shift
[[ $exit_code ]] && # do nothing if no error code passed
((exit_code != 0)) && { # do nothing if error code is 0
printf 'ERROR: %sn' "$@" >&2 # we can use better logging here
exit "$exit_code" # we could also check to make sure
# error code is numeric when passed
}
}
然后在运行测试用例后调用它:
run_test_case test_case_x
exit_if_error $? "Test case x failed"
要么
run_test_case test_case_x || exit_if_error $? "Test case x failed"
具有像exit_if_error
这样的错误处理程序的exit_if_error
是:
if
块的错误,测试退出码 相关文章
__FILE__
, __FILE__
__LINE__
等效 有几种方法可以解决这个问题。 假设您的一项要求是运行包含几个shell命令的shell脚本/函数,并检查脚本是否成功运行,并在出现故障时抛出错误。
shell命令通常依赖返回的退出代码来让shell知道它是成功的还是因某些意外事件而失败。
所以你想要做的是落在这两个类别上
根据您想要执行的操作,可以使用shell选项。 对于第一种情况,shell提供了set -e
选项,第二种情况下,您可以在EXIT
上执行trap
我应该在脚本/函数中使用exit
吗?
使用exit
通常会增强可读性在某些例程中,一旦知道了答案,就要立即退出到调用例程。 如果例程定义为一旦检测到错误时不需要进一步清理,则不立即退出意味着您必须编写更多代码。
因此,如果您需要对脚本执行清理操作以使脚本终止清理,则最好不要使用exit
。
我是否应该使用set -e
来退出时出错?
没有!
set -e
是尝试向shell中添加“自动错误检测”。 它的目标是让shell在发生错误时中止,但它带有很多潜在的陷阱,例如,
作为if测试的一部分的命令是免疫的。 在这个例子中,如果你期望在不存在的目录上进行test
检查,它不会,它会转到else条件
set -e
f() { test -d nosuchdir && echo no dir; }
f
echo survived
除了最后一个管道以外的命令都是免疫的。 在下面的例子中,因为最近执行的(最右边的)命令的退出代码被认为是( cat
)并且它是成功的。 这可以通过set -o pipefail
选项来避免,但它仍然是一个警告。
set -e
somecommand that fails | cat -
echo survived
建议使用 - 出口trap
判断是,如果你想能够处理一个错误而不是盲目退出,而不是使用set -e
,那么在ERR
伪信号上使用一个trap
。
当shell本身以非零错误代码退出时, ERR
陷阱不会运行代码,但当该shell运行的任何命令不是条件的一部分(如if cmd
或cmd ||
)时,都会退出非零退出状态。
通常的做法是我们定义一个陷阱处理程序,以提供有关哪条线路以及导致退出的附加调试信息。 请记住导致ERR
信号的最后一条命令的退出代码在此时仍然可用。
cleanup() {
exitcode=$?
printf 'error condition hitn' 1>&2
printf 'exit code returned: %sn' "$exitcode"
printf 'the command executing at the time of the error was: %sn' "$BASH_COMMAND"
printf 'command present on line: %d' "${BASH_LINENO[0]}"
# Some more clean up code can be added here before exiting
exit $exitcode
}
我们只是在失败的脚本的顶部使用这个处理程序
trap cleanup ERR
把它放在一个简单的脚本上,它包含了第15行的false
信息,这些信息就是你所得到的
error condition hit
exit code returned: 1
the command executing at the time of the error was: false
command present on line: 15
该trap
还提供了选项,不管错误如何,只要在shell完成时运行清理(例如,你的shell脚本退出),在信号EXIT
。 您也可以同时捕获多个信号。 可以在trap.1p - Linux手册页上找到要陷入的支持信号列表
另一件需要注意的事情是要明白,如果您正在处理子shell,则所提供的方法都不起作用,在这种情况下,您可能需要添加自己的错误处理。
在set -e
的子shell上不起作用。 false
仅限于子shell,并且永远不会传播到父shell。 要在这里执行错误处理,请添加您自己的逻辑来执行(false) || false
(false) || false
set -e
(false)
echo survived
trap
也一样。 由于上述原因,下面的逻辑将不起作用。
trap 'echo error' ERR
(false)
上一篇: Raise error in a Bash script
下一篇: How to find whether or not a variable is empty in Bash script