启用错误选项时,无法在Bash中使用增量操作

hbo*_*ert 1 bash

为什么以下代码段不起作用?

set -ue

inc=0
((inc++))
((inc++))
echo $inc
echo Here
[output nothing, return code 1]
Run Code Online (Sandbox Code Playgroud)

但是当禁用'-e'时它确实按预期工作?我用"GNU bash,版本4.3.46(1)-release"运行它

lar*_*sks 7

因此(来自bash手册页):

((表达))

根据ARITHMETIC EVALUATION下面描述的规则评估表达式.如果表达式的值不为零,则返回状态为0; 否则返回状态为1.这与let"expression"完全相同.

所以,当inc0你运行:

((inc++))
Run Code Online (Sandbox Code Playgroud)

...表达式的值是0(因为您正在使用后缀++运算符),因此返回值为1,这意味着您的脚本-e在生效时退出.解决此特定问题的最简单方法是使用前缀++运算符:

set -ue

inc=0
((++inc))
((++inc))
echo $inc
echo Here
Run Code Online (Sandbox Code Playgroud)

更新

正如@cdarke所提到的,您可以改为使用:命令,这是一个特殊的shell命令,意味着"除了评估所有参数之外什么都不做".您将经常在shell脚本中遇到这种情况,它用于变量默认值,如下所示:

: ${SOMEVAR:=somevalue}
Run Code Online (Sandbox Code Playgroud)

或者在while循环中,像这样:

while :; do
   ...
done
Run Code Online (Sandbox Code Playgroud)

所以代替:

((inc++))
Run Code Online (Sandbox Code Playgroud)

你可以这样做:

: $((inc++))
Run Code Online (Sandbox Code Playgroud)

但是你会发现有两处变化(这就是为什么我在原来的答案中没有提到它).因为:它本身就是一个命令,所以你不能再单独使用((...))语法(这完全等同于let命令).相反,您需要使用算术表达式语法$((...)).

你也可以这样做:

((inc++)) || true
Run Code Online (Sandbox Code Playgroud)

甚至:

((inc++)) || :
Run Code Online (Sandbox Code Playgroud)

其同样具有从表达式中抑制错误返回码的效果.

  • 另一种(但不一定更好)语法是使用`:`命令,它总是返回成功,如`:$((inc ++))`. (2认同)