bash set -e and i=0;let i++ do not agree
仅当变量的先验值为零时,带调试选项'set -e -v'的以下脚本才在增量运算符处失败。
1 2 3 4 5 6 | #!/bin/bash set -e -v i=1; let i++; echo"I am still here" i=0; let i++; echo"I am still here" i=0; ((i++)); echo"I am still here" |
bash(GNU bash版本4.0.33(1)-发行版(x86_64-apple-darwin10)以及GNU bash版本4.2.4(1)-发行版(x86_64-unknown-linux-gnu)
有任何想法吗?
我的问题的答案不是使用let(或shift或...),而是使用
1 | i=$((i+1)) |
当尝试通过设置'在非零状态代码上退出'来检查bash脚本时
1 | set -e |
bash手册指出set -e的作用是"如果简单命令以非零状态退出,则立即退出"。
不幸的是,let(和shift和...)返回计算结果("如果最后一个arg的值为0,则let返回1;否则返回0")。因此,获得状态返回值而不是状态码。有时,此返回值将为零,有时根据计算将为1。因此,set -e将导致脚本退出,具体取决于您的计算结果!除非您永远不使用它或求助于
1 | let i++ || true |
正如arnaud576875指出的那样,顺便说一句,这会增加CPU负担。
使用
1 | let ++i |
仅适用于i不为-1的特定情况,就像let i ++仅适用于i不为0的情况一样。因此,半解法。
虽然我喜欢Unix,但我别无选择。
如果
From the manual:
1 let arg [arg ...]Each arg is an arithmetic expression to be evaluated. If the last arg evaluates to 0, let returns 1; 0 is returned otherwise.
当
以下是一些解决方案:
1 2 3 | let ++i # pre-increment, if you expect `i` to never be -1 let i++ 1 # add an expression evaluating to non-zero let i++ || true # call true if let returns non-zero |
查看
Exit immediately if a simple command (see SHELL GRAMMAR above) exits with a non-zero status. [...]
因此,如果有任何语句返回非零的退出代码,则外壳程序将退出。
在
If the last arg evaluates to 0, let returns 1; 0 is returned otherwise.
可是等等!
同样,答案是使用增量运算符上的BASH联机帮助页:
id++ id--: variable post-increment and post-decrement
好吧,不太清楚。试试这个shell脚本:
1 2 3 4 5 6 | #!/bin/bash set -e -v i=1; let ++i; echo"I am still here" i=0; let ++i; echo"I am still here" i=0; ((++i)); echo"I am still here" |
嗯...按预期工作,我所做的就是在每行中将
但是,
我希望这是有道理的。