我在寻找答案时发现的恐怖故事...
好了,我有一个.sh脚本,它几乎完成了Jenkins应该做的所有事情:
之后清理自己的项目
因此,在Jenkins中,我只需通过在Execute Shell命令中运行脚本来“构建”项目。脚本已运行(源代码已下载,项目已构建/部署),但随后它会将构建标记为失败:构建步骤“Execute shell”标记为构建失败,即使脚本已成功运行!我尝试用以下命令关闭脚本:
退出退出命令0(仍将其标记为failure)
何时、如何以及为什么执行Shell将我的构建标记为失败?
发布于 2014-04-02 23:23:32
首先,将鼠标悬停在下面的灰色区域上。不是答案的一部分,但绝对必须说:
如果你有一个可以“签出、构建、部署”的shell脚本,那为什么还要用Jenkins呢?您放弃了Jenkins的所有特性,正是这些特性造就了Jenkins。您还可以使用cron或SVN post-挂钩直接调用脚本。Jenkins执行SVN结帐本身是至关重要的。它允许只有在发生更改时才触发构建(如果您愿意,也可以在计时器上或手动触发)。它跟踪构建之间的更改。它显示了这些更改,因此您可以看到哪个构建是针对哪组更改的。当提交者的更改导致构建成功或失败时,它会向提交者发送电子邮件(同样,根据您的喜好进行配置)。它将向提交者发送电子邮件,当他们修复了失败的构建时。而且越来越多。Jenkins对工件进行归档也使它们在每次构建时都可以直接从Jenkins获得。虽然不像SVN结帐那么重要,但这再次成为了Jenkins的一个组成部分。部署也是如此。除非您只有一个环境,否则通常会在多个环境中进行部署。Jenkins可以通过使用Promotions来跟踪特定构建(具有特定SVN更改集)部署在哪个环境中。你放弃了这一切。听起来好像有人告诉你“你必须使用Jenkins”,但你并不是真的想这样做,而且你这样做只是为了让你的老板不再烦你,只是为了勾选“是的,我已经使用了Jenkins”。
简短的答案是:Jenkin的的执行外壳构建步骤的最后一个命令的退出代码决定了构建步骤的成功/失败。0
-成功,anything else
-失败。请注意,这决定了构建步骤的成败,而不是整个作业运行的成败。整个作业运行的成功/失败可能进一步受到多个构建步骤以及构建后操作和插件的影响。
您已经提到了Build step 'Execute shell' marked build as failure
,所以我们将只关注一个构建步骤。如果Execute shell构建步骤只有一行调用您的shell脚本,那么shell脚本的退出代码将决定构建步骤的成功或失败。如果您有更多的行,在您的shell脚本执行之后执行,然后仔细检查它们,因为它们是可能导致失败的那些行。
最后,请阅读此处的。它与您问题没有直接关系,但请注意Jenkins使用/bin/sh -xe
启动Execute shell构建步骤的部分
-e
意味着,即使只有一个命令失败,shell脚本也会退出,如果您对该命令执行错误检查,则会退出(因为脚本在执行错误检查之前就退出了)。这与shell脚本的正常执行相反,shell脚本通常会打印失败命令的错误消息(或将其重定向到null并通过其他方式处理),然后继续执行。
要避免此问题,请将set +e
添加到shell脚本的顶部。
既然您说您的脚本完成了它应该做的所有事情,那么失败的命令很可能就在脚本的末尾。也许是最后一个回声?或者是某个地方的文物复制品?在没有看到完整的控制台输出的情况下,我们只是猜测。
请发布作业运行的控制台输出,最好是shell脚本本身,然后我们可以准确地告诉您哪一行失败了。
发布于 2014-12-02 14:23:20
对你的问题的简单简短的回答是
请将以下代码行添加到“执行shell”构建步骤中。
#!/bin/sh
现在让我向您解释为什么我们需要“执行Shell”构建作业的这一行。
默认情况下,Jenkins使用/bin/sh -xe
,这意味着-x
将打印每个command.And的另一个选项-e
,当任何命令以非零(当任何命令失败)退出时,这会导致外壳立即停止运行脚本。
因此,通过添加#!/bin/sh
将允许您在没有选项的情况下执行。
发布于 2017-03-17 19:55:51
在我看来,关闭shell的-e
选项是一个非常糟糕的主意。最终,脚本中的某个命令将由于磁盘空间不足或网络错误等瞬时条件而失败。如果没有-e
,Jenkins就不会注意到这一点,并会愉快地继续下去。如果你已经设置了Jenkins来做部署,这可能会导致糟糕的代码被推送,并使你的网站瘫痪。
如果脚本中有一行预期会失败的行,比如grep或find,那么只需在该行的末尾添加|| true
即可。这确保了这一行总是返回成功。
如果需要使用退出代码,可以将命令放入If语句中:
grep foo bar; if [ $? == 0 ]; then ... --> if grep foo bar; then ...
或者,您可以在||
子句中捕获返回代码:
grep foo bar || ret=$?
https://stackoverflow.com/questions/22814559
复制相似问题