返回shell脚本中的最后一个非零返回码

时间:2013-06-25 21:42:58

标签: shell exit

我正在运行构建脚本并希望它完成,但如果出现问题则返回非零返回码。到目前为止,我知道这样做的唯一方法是:

command1
rc1=$?

command2
rc2=$?

...

commandn
rcn=$?

exit $rc1 + $rc2 + ... + $rcn

有没有更好的方法来执行此操作,类似于pipefail但是对于非管道命令?

更新:我实际上想要总和(我认为这也不谨慎) - 只是一个非零的错误返回。我正在运行一个脚本,我希望构建在出现问题时失败,但是要完成构建,这样即使某些验证检查失败,我们也可能处于可运行状态。

6 个答案:

答案 0 :(得分:2)

那可能不是你想要的

您可能不想添加错误代码,因为它们变得毫无意义。相反,最好在遇到的第一个错误时退出并显示它。

您可以通过将命令与&& operator

一起链接来执行此操作
command1 \
&& command2 \
&& command3 \
|| echo "command failed: $?"

例如:

➤ echo show && (exit 188) && echo noshow || echo "failed: $?"
show
failed: 188

如果你必须......

您可以使用一个跟踪退出值的函数来包装命令:

SUM_EXIT=0

wrap() {
  eval "$@"
  SUM_EXIT=$(($SUM_EXIT+$?))
}

wrap command1
wrap command2
wrap command3

exit $SUM_EXIT

请注意,这是(IMO)对eval的完全有效用途。您将运行自己编写的命令。请注意可能包含换行符的奇怪文件名和参数。如果您不确定,请完全引用命令:

➤ wrap "(echo \"this is a 
newline containing string\" && exit 5)"
➤ echo $SUM_EXIT
5

答案 1 :(得分:1)

如果bash是一个选项。

跟踪“累积”返回代码

declare -i rc=0
command1 || ((rc += $?))
command2 || ((rc += $?))
command3 || ((rc += $?))
exit $rc

如果您需要跟踪失败的命令数而不是它们的返回码

declare -i rc=0
command1 || ((++rc))
command2 || ((++rc))
command3 || ((++rc))
exit $rc

答案 2 :(得分:0)

也许这就是你要找的东西:如果你不想在第一个命令失败后继续训练,你可以在脚本顶部set -e让它在第一个命令后立即退出(不是像if cmd这样的控制结构的一部分)退出非零。

您的shell手册包含所有详细信息。我的Bourne Shell说:

 -e errexit
         Exit immediately if any untested command fails in non-interactive
         mode.  The exit status of a command is considered to be explic-
         itly tested if the command is part of the list used to control an
         if, elif, while, or until; if the command is the left hand oper-
         and of an ``&&'' or ``||'' operator; or if the command is a pipe-
         line preceded by the ! operator.  If a shell function is executed
         and its exit status is explicitly tested, all commands of the
         function are considered to be tested as well.

答案 3 :(得分:0)

当你要求更好的方法来做到这一点(但我确信这不是最优雅和最好的方式),你可以这样做:

rc=0

command1
rc=$(($rc+=$?))

command2
rc=$(($rc+=$?))

...

commandn
rc=$(($rc+=$?))

exit $rc

答案 4 :(得分:0)

解决方案zmo的稍微简化的变体建议:

((rc+=$?))

如果你只是对返回代码是否与零不同感兴趣,你可以使用逻辑运算符:

rc=$((rc || $?))

答案 5 :(得分:0)

首先,总结返回值是一个非常糟糕的主意,因为返回值使用模256减少,下一个维护者会诅咒你必须添加代码以找出它失败的地方。这意味着如果总和是256的倍数,它将返回0(也称为成功),这不是OP想要的。

其次,除了一个简单的整数之外,你不能返回任何东西。无法返回返回值数组。

要使exit code sum解决方案有效,您必须

if [ "${rc-0}" -lt 256 ]
then
    return ${rc-0}
else
    return 255
fi

那就是说,我的+1转到set -e解决方案。如果命令失败,简单地继续处理是一个坏主意。如果他们彼此依赖,你可能会看到意想不到的结果,如果他们不这样做,为什么他们在同一个脚本中呢?