Bash 即使其中一个调用的程序失败,也将Hudson作业解释为成功
我有一份Hudson的工作,定期合并来自上游bazaar存储库的更改 当前,当上游没有更改时,Hudson将此作业报告为失败,因为bzr commit命令返回时出错。我的脚本看起来像这样:Bash 即使其中一个调用的程序失败,也将Hudson作业解释为成功,bash,hudson,bazaar,Bash,Hudson,Bazaar,我有一份Hudson的工作,定期合并来自上游bazaar存储库的更改 当前,当上游没有更改时,Hudson将此作业报告为失败,因为bzr commit命令返回时出错。我的脚本看起来像这样: bzr branch lp:~lorinh/project/my-local-branch cd my-local-branch REV_UPSTREAM=`bzr version-info lp:project --custom --template="{revno}"` bzr merge lp:proj
bzr branch lp:~lorinh/project/my-local-branch
cd my-local-branch
REV_UPSTREAM=`bzr version-info lp:project --custom --template="{revno}"`
bzr merge lp:project
bzr commit -m "merged upstream version ${REV_UPSTREAM}"
./run_tests.sh
bzr push lp:~lorinh/project/my-local-branch
如果没有要合并的更改,Hudson控制台输出将如下所示:
+ bzr branch lp:~lorinh/project/my-local-branch
Branched 807 revision(s).
+ bzr merge lp:project
Nothing to do.
+ bzr commit -m merged upstream version 733
Committing to: /var/lib/hudson/jobs/merge-upstream/workspace/myproject/
aborting commit write group: PointlessCommit(No changes to commit)
bzr: ERROR: No changes to commit. Use --unchanged to commit anyhow.
Sending e-mails to: me@example.com
Finished: FAILURE
问题是,我不想让哈德逊报告这是一个失败。如何修改命令,使脚本在提交失败时终止,但Hudson不会将其解释为错误?我尝试将commit命令更改为:
bzr commit -m "merged upstream version ${REV_UPSTREAM}" || exit
但那没用
(注意:我意识到我可以使用Hudson的“Poll SCM”而不是“定期构建”。但是,在bazaar中,如果有人使用在最近的修改之前完成的本地提交进行推送,那么Hudson将不会检测到存储库的更改。)考虑到bzr似乎没有发出正确的退出代码(基于您的
bzr…| | exit
示例),一种解决方案是捕获bzr的输出,然后扫描错误或其他
bzr commit -m "merged upstream version ${REV_UPSTREAM}" 2>&1 | tee /tmp/bzr_tmp.$$
case $( < /tmp/bzr_tmp.$$ ) in
*ERROR* )
printf "error running bzr, found error msg = $(< /tmp/bzr_tmp.$$)\n"
exit 1
;;
* )
: # everything_OK this case target
# just to document the default action of 'nothing' ;-)
;;
esac
bzr commit-m“合并上游版本${REV_upstream}”2>&1|tee/tmp/bzr_tmp$$
案例$(
根据示例输出,一个稍微简单的case target regex是*FAILURE).
$(
是shell的一个较新功能,您可以将其视为$(cat file)
,但它在使用进程资源方面更有效,因为它不需要启动新进程(cat
)来转储文件
我希望这有帮助。鉴于bzr似乎没有发出正确的退出代码(基于您的
bzr…| | exit
示例),一种解决方案是捕获bzr的输出,然后扫描错误或其他
bzr commit -m "merged upstream version ${REV_UPSTREAM}" 2>&1 | tee /tmp/bzr_tmp.$$
case $( < /tmp/bzr_tmp.$$ ) in
*ERROR* )
printf "error running bzr, found error msg = $(< /tmp/bzr_tmp.$$)\n"
exit 1
;;
* )
: # everything_OK this case target
# just to document the default action of 'nothing' ;-)
;;
esac
bzr commit-m“合并上游版本${REV_upstream}”2>&1|tee/tmp/bzr_tmp$$
案例$(
根据示例输出,一个稍微简单的case target regex是*FAILURE).
$(
是shell的一个较新功能,您可以将其视为$(cat file)
,但它在使用进程资源方面更有效,因为它不需要启动新进程(cat
)来转储文件
我希望这会有帮助。你非常接近!以下是您尝试的更正版本:
bzr commit -m "merged upstream version ${REV_UPSTREAM}" || exit 0
现在,它满足了您的要求,但并不完美。我以后再谈
请注意与您的版本相比有一个微小的重要变化——我们现在明确表示,如果bzr命令不这样做,我们应该使用代码0(成功)退出。在您的版本中,exit(不带参数)将终止脚本,但返回最后执行的命令的退出代码——在本例中是bzr commit
关于退出的更多信息
我们如何了解这种退出行为?exit
命令是一个内置的shell-要查找有关它的文档,我们使用help命令:
help exit
在我的机器上告诉我:
exit: exit [n]
Exit the shell.
Exits the shell with a status of N. If N is omitted, the exit status
is that of the last command executed.
这是一张像样的支票
哈德逊和出口代码
Hudson遵循这种常见的惯例,将退出代码0解释为成功,将任何其他代码解释为失败。如果它执行的构建脚本以非零代码退出,它会将您的构建标记为失败
为什么您的脚本在bzr提交后停止
如您所说,如果您有以下内容,并且您的脚本在bzr提交后停止
bzr commit -m "merged upstream version ${REV_UPSTREAM}"
./run_tests.sh
。。。我怀疑您的脚本中有一条指令,比如set-e
,或者正在使用bash-e build\u script.sh
如果命令以非零状态退出,这两种方法都会告诉shell立即退出,并传递相同的“失败”退出代码。(有一些微妙之处——见脚注1)
禁用出错退出
虽然这种在出错时退出的行为非常有用,但有时我们希望暂时禁用它。你找到了一条路,在
bzr commit whatever || true
我们还可以使用set+e禁用错误检查
这是一个你可能会发现有用的模式。在这方面,我们将:
设置+e
)bzr commit which
设置-e
)set +e
bzr commit whatever
commit_status=$?
set -e
if [[ "$commit_status" != "0" ]]; then
echo "bzr commit finds nothing to do. Build will stop, with success"
exit 0
fi
echo "On we go with the rest of the build script..."
注意,我们用set+e/set-e尽可能少地括起来。如果我们在那一部分的脚本中有拼写错误,他们就不会停止脚本,就会出现混乱。阅读文章“”中的“避免集合-e”部分,了解更多想法
foo | |退出0有什么问题?
正如我前面提到的,我们提出的第一个解决方案存在一个问题。我们已经说过,当bzr commit
为非零(即它不正常提交)时,我们将始终停止并指示成功。即使bzr commit
由于其他原因(以及其他非零退出代码)失败,也会发生这种情况:可能是您在命令调用中输入了错误,或者bzr无法连接到repo
至少在某些情况下,您可能希望将构建标记为失败,这样您就可以对此采取措施
寻求更好的解决方案