Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 即使其中一个调用的程序失败,也将Hudson作业解释为成功_Bash_Hudson_Bazaar - Fatal编程技术网

Bash 即使其中一个调用的程序失败,也将Hudson作业解释为成功

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

我有一份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: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
  • 对任何命令的退出代码进行测试和操作
  • 让我们实现这一点。如果bzr命令失败,我们将再次退出0(成功)

    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

    至少在某些情况下,您可能希望将构建标记为失败,这样您就可以对此采取措施

    寻求更好的解决方案