如果出错,如何退出 bash 功能?
Posted
技术标签:
【中文标题】如果出错,如何退出 bash 功能?【英文标题】:How to exit bash function if error? 【发布时间】:2017-03-18 17:05:19 【问题描述】:我正在制作一个预提交脚本。它看起来像这样:
function presubmit()
gradle test android
gradle test ios
gradle test server
git push origin master
如果任何测试失败,我希望函数退出,这样它就不会将错误推送到 git。怎么样?
【问题讨论】:
tldp.org/LDP/abs/html/exit-status.html 你可以看看thisgradle ... || return
?
每个人都假设gradle
在测试失败时将有非零退出。情况可能并非如此。我没有看到文档说 gradle 将在测试失败时返回非零。需要注意的是,该函数正在调用gradle
来测试某个操作系统。 gradle
本身不会失败,但它进行的测试可能不会通过。
【参考方案1】:
1.使用子shell ( .. )
和set -e
;为了更简洁,你可以这样做:
build() ( set -e # Fail early
build_cmd_step_1
build_cmd_step_2
build_cmd_step_3
...
)
那么,函数会在第一次失败时失败,你可以拦截退出状态:
build
exit_status=$?
if [ $exit_status -ne 0 ]; then
echo "We have error - build failed!"
exit "$exit_status"
fi
2。或者,函数内的&& \
链接 也很好(https://***.com/a/51913013/1375784),但如果你有更大的函数,它可能会变得很糟糕。
这两种方法都不错,具体取决于您的用例(在某些情况下,使用子外壳可能会导致一些不需要的副作用)
【讨论】:
确保不要将build
与测试一起运行,因为它会停用set -e
。所以if ! build; then...
甚至if [ build -ne 0 ]; then ..
都不会按预期工作。
它也不能作为管道的一部分工作,例如build || echo "build failed"
请注意,当在函数内部或将要获取源的脚本中使用时,return "$exit_status"
通常比exit "$exit_status"
更合适。 ***.com/questions/4419952/…
@ZombieDev 你有什么解释为什么会这样吗?我的意思是,这很奇怪,如果你调用一个带有set -e
子shell 的函数,如果你执行|| anything
,它将被忽略【参考方案2】:
我这样做的方法是在函数中的每个命令之后添加&& \
(最后一个除外)。
function presubmit()
gradle test android && \
gradle test ios && \
gradle test server && \
git push origin master
【讨论】:
这看起来是最干净的解决方案,因为在 ~/.bashrc 的函数中使用set -e
会导致终端退出。
是否需要反斜杠?我认为&&
后跟换行符的解析方式相同。也许它不是可移植的功能。【参考方案3】:
我会让脚本更细化:
#!/bin/bash
function test()
gradle test android
gradle test ios
gradle test server
function push()
git push origin master
# this subshell runs similar to try/catch
(
# this flag will make to exit from current subshell on any error inside test or push
set -e
test
push
)
# you catch errors with this if
if [ $? -ne 0 ]; then
echo "We have error"
exit $?
fi
我们只在测试和推送中跟踪错误。您可以在测试和推送运行的子外壳之外添加更多操作。您也可以通过这种方式为错误添加不同的范围(让我们将其视为 try/catch)
【讨论】:
【参考方案4】:你可以这样做:
# declare a wrapper function for gradle
gradle()
command gradle "$@" || exit 1
presubmit()
gradle test android
gradle test ios
gradle test server
git push origin master
declare -xf presubmit gradle
在子shell中调用函数:
( presubmit )
【讨论】:
【参考方案5】:通常当我调用一个函数并想要一条错误消息以防它失败时,我会这样做:
presubmit || echo 'presubmit failed' ; exit 1;
通过添加||
标志,它将判断哪个表达式是否为TRUE。
希望这会有所帮助:)
【讨论】:
OP 希望presubmit
在执行git push
之前提前退出。这只是说明如何在presubmit
以非零退出状态退出时做一些额外的事情。以上是关于如果出错,如何退出 bash 功能?的主要内容,如果未能解决你的问题,请参考以下文章
SetParent 装载的窗体 会保留在进程中 如果程序运行中出错,包括更新,查询.... 出错, 该如何卸载窗体
shell脚本怎么设置语句出错自动退出?(set -eset -o errexit)使用未初始化的变量自动退出?(set -uset -o nounset)(退出脚本)
使用pecl安装php扩展时出错-bash: pecl: command not found
shell脚本怎么设置语句出错自动退出?(set -eset -o errexit)使用未初始化的变量自动退出?(set -uset -o nounset)(退出脚本)shell set