如果 shell 脚本的一部分失败,如何退出该脚本?

如果 shell 脚本的一部分失败,如何退出该脚本?

如何编写一个 shell 脚本,如果其中一部分失败,该脚本就会退出?例如,如果以下代码片段失败,则脚本应退出。

n=0
until [ $n -ge 5 ]
do
  gksu *command* && break
  n=$[$n+1]
  sleep 3

答案1

一种方法是添加set -e到脚本的开头。这意味着(来自help set):

  -e  Exit immediately if a command exits with a non-zero status.

因此,如果任何命令失败,脚本将退出。

或者,您可以exit在可能的失败点添加显式语句:

command || exit 1

答案2

您可以使用关键字在任何位置退出脚本exit。您还可以指定退出代码,以便向其他程序指示您的脚本失败或如何失败,例如exit 1等等exit 2。(按照惯例,退出代码 0 表示成功,任何大于 0 的值表示失败;但是,按照惯例,退出127 以上的代码保留用于异常终止(例如通过信号)。

失败时退出的通用结构是

if [ failure condition ]; then
    exit n
fi

与合适的failure conditionn.但在特定情况下,您可能会采取不同的处理方式。现在,对于您的情况,我解释您的问题,如果五次调用中的任何一个gksu失败,那么您的意思是退出。一种方法是使用这样的函数

function try_command {
    for i in 1 2 3 4 5 ; do
        if gksu command ; then
            return 0
        fi
    fi
    exit 1
}

然后,通过 调用循环try_command

有(更)高级或更复杂的方法来解决您的问题。然而,上面的解决方案比 Stephane 的解决方案更适合初学者。

答案3

attempt=0
until gksu command; do
  attempt=$((attempt + 1))
  if [ "$attempt" -gt 5 ]; then
    exit 1
  fi
done

exit退出脚本,除非在子 shell 中调用它。如果脚本的该部分位于子 shell 中,例如因为它位于管道内(...)或管道的一部分,那么它只会退出$(...)那个子壳

在这种情况下,如果您想要脚本要除了子 shell 之外还退出,那么您需要调用exit该子 shell 退出。

例如,这里有 2 层嵌套的子 shell:

(
  life=hard
  output=$(
    echo blah
    [ "$life" = easy ] || exit 1 # exit subshell
    echo blih not run
  ) || exit # if the subshell exits with a non-zero exit status,
            # exit as well with the same exit status

  echo not run either
) || exit # if the subshell exits with a non-zero exit status,
          # exit as well with the same exit status

如果子 shell 是管道的一部分,事情会变得更加棘手。bash有一个特殊的$PIPESTATUS数组,类似于zsh$pipestatus数组,可以在这里为您提供帮助:

{
   echo foo
   exit 1
   echo bar
} | wc -c
subshell_ret=${PIPESTATUS[0]}
if [ "$subshell_ret" -ne 0 ]; then
  exit "$subshell_ret"
fi

答案4

pass_to_functio()
{
  echo "command exited with status $1"
}

(
 exec <Any Command >  &
 child_pid=$!
 wait $child_pid
 pass_to_function $?
)&

相关内容