如何将一个函数作为一个"测试命令"并在失败时执行操作,同时在发生错误时仍然中止该功能? 请考虑以下脚本
#!/bin/bash -e
function foo() {
echo Entering foo
false
echo Should not reach this line
}
foo || echo I want to see this line on failure in foo
foo
我得到的输出是
Entering foo
Should not reach this line
Entering foo
虽然我想得到
Entering foo
I want to see this line on failure in foo
Entering foo
我想我正在寻找的是一种将该功能标记为未经测试的命令的方法。根据bash手册页
-e errexit
Exit immediately if any untested command fails in non-interactive
mode. The exit status of a command is considered to be explicitly
tested if the command is part of the list used to control an if,
elif, while, or until; if the command is the left hand operand of
an “&&” or “||” operator; or if the command is a pipeline preceded
by the ! operator. If a shell function is executed and its exit
status is explicitly tested, all commands of the function are con‐
sidered to be tested as well.
修改 预期的产出是错误的。编辑它是为了清晰
答案 0 :(得分:2)
set -e
在foo
的第一次通话中被停用,因为它位于||
的左侧。
此外,您永远不会看到I want to see this ...
字符串被输出,除非echo
中的最后foo
以某种方式失败(这是echo
中的最后foo
确定函数的退出状态。)
foo() {
echo Entering foo
false && echo Should not reach this line
}
foo || echo I want to see this line on failure in foo
foo
以上输出(有或没有set -x
)
Entering foo
I want to see this line on failure in foo
Entering foo
现在false
是foo
中最后执行的语句。
答案 1 :(得分:0)
我最终将代码包装在下面的实用程序函数中。
#!/bin/bash -e
# Runs given code aborting on first error and taking desired action on failure
# $1 code to invoke, can be expression or function name
# $2 error handling code, can be function name or expressions
function saferun {
set +e
(set -E ; trap 'exit 1' ERR ; eval $1)
[ $? -ne 0 ] && eval $2
set -e
}
function foo() {
echo Entering foo
false
echo Should not reach this line
}
saferun foo "echo I want to see this line on failure in foo"
foo
让我们分解一下:
set +e
和set -e
用于抑制错误失败,否则脚本将在第一次出错时退出trap
用于中止执行任何错误(而不是set -e
)()
用于在子shell中运行给定代码,因此外部脚本将在失败后继续运行,并且set -E
用于将陷阱传递到子shell中。所以(set -E ; trap 'exit 1' ERR ; eval $1)
运行给定的代码/函数在第一次错误时中止而不退出整个脚本$? -ne 0
检查失败,eval $2
运行错误处理代码