【问题标题】:How to make a shell script fail the build on unsuccesfull execution?如何使 shell 脚本在执行不成功时使构建失败?
【发布时间】:2014-03-20 16:28:59
【问题描述】:

我有一个在 CI 服务器上执行的 shell 脚本,该 shell 脚本与 Curl 的 . 现在,如果 curl 不成功,我希望脚本失败,我读到“$?”将给出执行语句的状态,我如何使用它来实现我想要的?

function do_curl 
    {
      echo "==== Posting $file_name to DHIS ===="
      curl -H "Content-Type: application/json" -u $authorization -d @$file_name $url -X POST || exit
      echo ""
    }

这个函数被重复调用,我希望它在第一次失败时退出,现在,它不会退出,而是执行它调用的次数,即使它第一次失败。

【问题讨论】:

  • 不够好。将|| exit 放在函数内的调用上退出shell,而不仅仅是函数,所以同样,您仍然在某个地方有一个子shell,大概是函数本身的外部
  • 顺便说一下,function foo { 不是定义函数的 POSIX 兼容方式。如果您希望您的代码与其他 shell 兼容,请使用 foo() {,不带 function 关键字。
  • 另外,你需要更多的引号来避免字符串分割。 -u "$authorization"-d "@$file_name""$url" 等,否则当您的文件名、授权内容等包含空格、全局字符等时,您就会遇到错误。
  • 顺便说一句——你确定 curl 实际上是以非零值退出的吗?如果遇到 500 错误但仍以状态 0 退出,则可能需要使用 curl --fail
  • 在我更新的答案中,您可能会在这里找到您要查找的内容:stackoverflow.com/questions/9893667/…

标签: shell scripting


【解决方案1】:
curl --fail ... || exit

...如果 curl 调用失败,将立即以 curl 的退出状态退出 shell 脚本。

也可以使用set -e 获得全局失败时退出行为,但这只能由专家完成;请参阅 http://mywiki.wooledge.org/BashFAQ/105 了解其局限性和缺陷的讨论。

【讨论】:

  • 我试过了,它不起作用,它的作用是,它在控制台上抛出一个错误,但仍然继续执行其他语句。
  • @user1537766,如果是这种情况,您在子外壳中运行,并且不仅需要退出直接外壳,还需要退出其父外壳,或者重组您的代码以不再完全产生一个子shell。在任何这些情况下,我们都需要更多的上下文来提供帮助。
  • 你是对的,我正在生成一个子shell,它现在就像魅力一样!谢谢!
【解决方案2】:

更新:

有关使用函数的问题的可能答案(原始问题没有函数),请参见此处:Is there a way to write a bash function which aborts the whole execution, no matter how it is called?

(您也可以进一步更新您的问题以获得更好的答案)


一种可能的解决方案是对每一行都使用类似的东西:

curl ... || exit

当然,如果你有多个 url,你可以将它们封装在一个函数中,或者你可以这样链接它们:

curl ... && curl ... && ...

您也可以像这样使用\ 中断当前行:

curl ... && \
curl ... && \
...

这也有效,因为没有显式 exit 语句的脚本应该返回最后设置的退出代码,例如在这种情况下,由最后执行的 curl 命令返回。


关于使用的运算符:

a || b 

意思是:评估a OR b|| 逻辑上应用于a 的返回码,所以如果a 返回0not 0b 将无论如何都要执行。

a && b

意思是:执行a AND b&& 又在逻辑上应用于a 的返回码,所以如果a 返回0 (=false),b 就赢了' 不会执行,因为评估将在该点停止,但如果 a 返回值 not 0 (=true),则评估和执行将继续。

您还可以将它与使用括号(())和其他东西的子shell 结合起来构建一些相当复杂的命令链,但我建议遵循 KISS(“保持简单,愚蠢!”)在 shell 脚本的情况下的原则,最好将所有内容写在自己的行上,另外注释(使用#),所以如果你必须在一年后查看它,你仍然知道脚本的作用;)

虽然这些东西在我迄今为止使用的所有 shell 上都是相同的,但仍然可能存在差异,但如果您像我一样在大多数机器上都安装了 bash,那么您可能会感兴趣:

Bash Reference Manual

【讨论】:

  • 没有理由明确传递$?; exit 隐式使用 $?
  • @CharlesDuffy 你发表评论的速度比我完成编辑的速度要快;)但感谢您指出这一点;)
  • 拜托,拜托不要将人们指向 ABS。我发誓,我们在 Freenode 的#bash 频道中的一半工作是帮助人们改掉他们在那里养成的坏习惯。
  • @CharlesDuffy 虽然我并没有真正理解 ABS 的问题,但我现在已将指针替换为指向 bash 参考手册的指针,这也有帮助(尽管恕我直言,您需要更多时间来查找你在寻找通常比在 ABS 中)
  • 如果您想要一个由关心准确性的人积极维护的参考,我建议mywiki.wooledge.org/BashGuide。 ABS 的维护人员经常缺席,并且一直忽视对与最佳实践相矛盾的示例的投诉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-01
  • 1970-01-01
相关资源
最近更新 更多