[英]Bash functions ignore set -e
如何将 function 作为“测试命令”运行并对失败执行操作,同时在发生错误时仍中止 function? 考虑以下脚本
#!/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
我得到的 output 是
Entering foo
Should not reach this line
Entering foo
虽然我想得到
Entering foo
I want to see this line on failure in foo
Entering foo
我想我正在寻找一种将 function 标记为未经测试的命令的方法。 根据 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.
编辑预期的 output 是错误的。 为清楚起见对其进行了编辑
set -e
在第一次调用foo
被禁用,因为它位于||
的左侧 。
另外,您永远也不会看到I want to see this ...
输出的I want to see this ...
字符串,除非foo
的最后一个echo
以某种方式失败了(这是foo
中的最后一个echo
决定了函数的退出状态)。
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
最后执行的语句。
我最终将代码包装到了下面的实用程序函数中。
#!/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
用于将trap传递给子壳。 因此(set -E ; trap 'exit 1' ERR ; eval $1)
在没有退出整个脚本的情况下,在第一个错误时运行给定的代码/函数中止 $? -ne 0
$? -ne 0
检查失败,并且eval $2
运行错误处理代码
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.