2016-11-05 26 views
1

为什么以下代码段不起作用?错误选项启用时不能在Bash中使用递增操作

set -ue 

inc=0 
((inc++)) 
((inc++)) 
echo $inc 
echo Here 
[output nothing, return code 1] 

但是,当禁用'-e'它确实按预期工作?我跑这跟 “GNU的bash,版本46年3月4日(1)-release”

+1

这是为什么不使用'set -e'的原因之一。有太多的命令可以具有非零的退出状态,而不会实际指示错误。 – chepner

+1

[BashFAQ#105](http://mywiki.wooledge.org/BashFAQ/105)直接讨论这一点。 –

回答

7

因此(从bash手册页):

((表达式))

在ARITHMETIC EVALUATION下根据下面描述的规则 评估表达式。如果表达式的值为 非零,则返回状态为0;否则返回状态为1. 这与让“表达式”完全等价。

所以当inc0,并且在运行:

((inc++)) 

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

set -ue 

inc=0 
((++inc)) 
((++inc)) 
echo $inc 
echo Here 

更新

由于@cdarke提到,你可以改用:命令,这是一个特殊的shell命令意味着“除了评估所有论点之外别无他物”。你会经常遇到这样的shell脚本在那里它被用于变量默认是这样的:

: ${SOMEVAR:=somevalue} 

还是在while循环,就像这样:

while :; do 
    ... 
done 

所以不是:

((inc++)) 

您可以做到这一点:

: $((inc++)) 

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

你也可以做这样的事情:

((inc++)) || true 

甚至:

((inc++)) || : 

这同样具有表达抑制错误返回代码的效果。

+2

另一种(但不一定更好)的语法是使用总是返回成功的':'命令,如在':$((inC++))'中。 – cdarke

+0

@cdarke:我会说这是更好的;甚至“更好” – rici

+0

这是如此明显,我应该已经明白了这一点。 – hbogert

相关问题