如果出错,如何退出bash函数?

Xi *_*ang 11 bash

我正在制作一个预先提交的脚本.它看起来像这样:

function presubmit() {
  gradle test android
  gradle test ios
  gradle test server
  git push origin master
}
Run Code Online (Sandbox Code Playgroud)

我希望函数退出,如果任何测试失败,那么它不会将bug推送到git.怎么样?

小智 22

1.使用子shell( .. )set -e; 为了使它更简洁,你可以这样做:

build() {( set -e        # Fail early
  build_cmd_step_1
  build_cmd_step_2
  build_cmd_step_3
  ...
)}
Run Code Online (Sandbox Code Playgroud)

然后,该函数将在第一次失败时失败,您可以拦截退出状态:

build
exit_status=$?
if [ ${exit_status} -ne 0 ]; then
  echo "We have error - build failed!"
  exit "${exit_status}"
fi
Run Code Online (Sandbox Code Playgroud)

2. 或者,&& \函数内部的链接也很好(/sf/answers/3633910941/),但如果你有更大的函数可能会变坏。

两种方法都可以,这取决于您的用例(在某些情况下使用子外壳可能会导致一些不需要的副作用)

  • 确保不要将“build”与测试一起运行,因为它会停用“set -e”。所以`如果!建造; then...` 甚至 `if [ build -ne 0 ]; 那么..`将无法按预期工作。 (4认同)
  • 它也不能作为管道的一部分工作,例如“build ||” echo“构建失败”` (2认同)

Dre*_*pin 9

我的方法是&& \在函数中的每个命令之后添加(最后一个命令除外)。

function presubmit() {
    gradle test android && \
    gradle test ios && \
    gradle test server && \
    git push origin master
}
Run Code Online (Sandbox Code Playgroud)

  • 这似乎是最干净的解决方案,因为在〜/ .bashrc中的函数中使用`set -e`会导致终端退出。 (2认同)

Kos*_*nos 6

我会让脚本更细化:

#!/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
Run Code Online (Sandbox Code Playgroud)

我们仅在测试和推送中跟踪错误。您可以在运行测试和推送的子 shell 之外添加更多操作。您还可以通过这种方式添加不同的错误范围(让我们将其视为 try/catch)


anu*_*ava 5

你可以这样做:

# 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
Run Code Online (Sandbox Code Playgroud)

在子 shell 中调用该函数如下:

( presubmit )
Run Code Online (Sandbox Code Playgroud)


Mic*_*khi 4

通常,当我调用一个函数并希望在失败时收到错误消息时,我会这样做:

presubmit || { echo 'presubmit failed' ; exit 1; }

通过添加||标志,将确定哪个表达式是否为 TRUE。

希望这可以帮助 :)

  • OP 希望在执行“git push”之前提前退出“presubmit”。这只是展示了如何在“presubmit”以非零退出状态退出时执行额外的操作。 (2认同)