只有当变量的先前值为零时,带有调试选项'set -e -v'的以下脚本才会在increment运算符处失败。
#!/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)-release(x86_64-apple-darwin10),还有GNU bash,版本4.2.4(1)-release(x86_64-unknown-linux-gnu))
任何想法?
答案 0 :(得分:18)
我的问题的答案不是使用让(或 shift ,或......)而是使用
i=$((i+1))
尝试通过
设置'退出非零状态代码'来检查bash脚本时set -e
bash手册指出 set -e 具有“立即退出的效果,如果一个简单的命令以非零状态退出。”。
不幸的是让(和 shift 和...)返回计算结果('如果最后一个arg的计算结果为0,则返回1;否则返回0 ')。因此,不是状态代码,而是获得某种返回值。有时这个返回值将为零,有时一个取决于计算。因此set -e将导致脚本退出,具体取决于您的计算结果!除非你不使用它或诉诸于
,否则它无关let i++ || true
正如arnaud576875指出的那样,btw增加了额外的CPU负担。
使用
let ++i
仅适用于我不是-1的特定情况,与 let i ++ 一样,仅当i不为0时才有效。因此半解决方案。
我喜欢Unix,但我没有别的办法。
答案 1 :(得分:9)
如果let
的最后一个参数评估为0
,则返回1
(因此,非零状态):
当从手册:
let arg [arg ...]
每个arg都是要评估的算术表达式。 如果最后一个arg的计算结果为0,则返回1 ;否则返回0。
i++
为i
时, 0
评估为零(因为它是后增量,因此返回i
的先前值),因此{{1} }返回let
,由于1
,bash存在。
以下是一些解决方案:
set -e
答案 2 :(得分:0)
查看set -e
上的BASH manpage:
如果一个简单的命令(参见上面的SHELL GRAMMAR)以非零状态退出,则立即退出。 [...]
因此,如果任何语句返回非零退出代码,则shell将退出。
在let
命令上查看BASH manpage:
如果最后一个arg的计算结果为0,则返回1;否则返回0。
但是等等! i++
的答案是一个而不是零!应该有用了!
同样,答案是使用增量运算符的BASH联机帮助页:
id ++ id--:变量后增量和后减量
好的,不太清楚。试试这个shell脚本:
#!/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"
嗯...按预期工作,我所做的只是在每一行中将i++
更改为++i
。
i++
是后增量运算符。这意味着,在{/ em> i
语句返回值后,它会增加let
。由于{<1}}在递增之前为,因此i
语句返回非零值。
但是,let
是预增量运算符。这意味着它在返回退出状态之前递增++i
。由于i
增加到i
,退出状态变为零。
我希望这是有道理的。