本文介绍了Bash函数忽略set -e的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
如何将功能作为经过测试的命令"运行并在失败时执行操作,同时在发生错误时仍中止功能?考虑以下脚本
How can I run a function as a "tested command" and perform action on failure, while still aborting the function as soon as an error occur?Consider the following script
#!/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手册页
I guess what I'm looking for is a way to mark the function as untested command. According bash man page
-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.
编辑预期的输出是错误的.为了清晰起见对其进行了编辑
EDITThe expected output was wrong. edited it for clarity
推荐答案
我最终将代码包装到了下面的实用程序函数中.
I ended up wrapping the code to do so in a utility function below.
#!/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
)()
用于运行给定的代码在subshell中,因此外部脚本在失败后将继续运行,并且使用set -E
将陷阱传递到subshell中.因此(set -E; trap'exit 1'ERR; eval $ 1)
在第一次错误时运行给定的代码/函数中止,而没有退出整个脚本 -
$?-ne 0
检查是否失败,并且eval $ 2
运行错误处理代码
set +e
andset -e
are used to suppress failure on error, as otherwise the script will just exit on first errortrap
is used to abort the execution on any error (instead ofset -e
)()
is used to run the given code in subshell, so outer script will keep running after failure, andset -E
is used to pass the trap into the subshell. so(set -E ; trap 'exit 1' ERR ; eval $1)
run the given code / function aborting on first error while not exiting the whole script$? -ne 0
check for failures andeval $2
runs the error handling code
这篇关于Bash函数忽略set -e的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!