bash set -o errexit 问题还是变量递增的方式?

bash set -o errexit 问题还是变量递增的方式?

我有一个 shell 脚本,使用 set -e 递增变量,如下例所示:

$ var=0; echo $?
0
$ ((var++)); echo $?
1
$ ((var++)); echo $?
0
$ ((var++)); echo $?
0
$ echo $var; echo $?
3
0
$ bash --version
GNU bash, version 4.2.46(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later  <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.    
$

脚本意外退出。问题是完全相同的脚本在 MacBook 上本地运行时以同样的方式退出。运行上面的示例时,MacBook 上的 bash shell 的行为方式完全相同。

有谁知道这里发生了什么事吗?

答案1

如果算术表达式的值非零,则算术命令成功。如果表达式的值为 0,则命令失败,状态为 1。这允许在测试中使用算术命令,因为 shell 算术表达式中的布尔运算符返回 0 表示 true,1 表示 false(如在 C 中)。例如

if ((x==3)); then …

之所以有效,是因为当等于 3((x==3))时返回 0 ,否则返回 1。$x

后缀增量运算符返回变量的旧值。因此,如果之前为零,则((var++))返回错误状态。var

set -e告诉 shell 在第一个命令失败时退出。那里没有什么惊喜。

为了避免可能合法地具有值 0 的算术表达式导致不必要的错误,请不要使用算术命令,而应使用带有算术表达式的普通赋值。

var=$((var+1))

答案2

您始终可以使用算术命令,例如((var++)).如果赋值之前 var 的值为 0,那么要强制获得成功的状态代码,您可以编写:((var++)) || true

或者你可以这样写来跳过 errexit 逻辑:! ((var++))

答案3

我使用declare -i i=0; i+=1,退出代码为零。

之前写过一个hacki=0; ((i++)) ||true

相关内容