bash set -e和i = 0;让i ++不同意

时间:2011-08-30 17:27:39

标签: bash shell set operator-keyword increment

只有当变量的先前值为零时,带有调试选项'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))

任何想法?

3 个答案:

答案 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,退出状态变为零。

我希望这是有道理的。