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

bli*_*ako 12 bash shell increment set operator-keyword

仅当变量的先前值为零时,以下带有调试选项'set -e -v'的脚本才会在增量运算符处失败.

#!/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"
Run Code Online (Sandbox Code Playgroud)

bash(GNU bash,版本4.0.33(1)-release(x86_64-apple-darwin10),还有GNU bash,版本4.2.4(1)-release(x86_64-unknown-linux-gnu))

有任何想法吗?

bli*_*ako 19

我的问题的答案不是使用let(或shift,或......)而是使用

i=$((i+1))
Run Code Online (Sandbox Code Playgroud)

尝试通过设置' 退出非零状态代码 ' 来检查bash脚本时

set -e
Run Code Online (Sandbox Code Playgroud)

bash手册指出,如果一个简单的命令以非零状态退出,则set -e具有" 立即退出 "的效果.".

不幸的是,(和shift和...)返回计算结果(' 如果最后一个arg计算为0,则返回1;否则返回0 ').因此,不是状态代码,而是获得某种返回值.有时这个返回值将为零,有时一个取决于计算.因此set -e将导致脚本退出,具体取决于计算结果!除非你不使用它或诉诸于它,否则无所事事

let i++ || true
Run Code Online (Sandbox Code Playgroud)

正如arnaud576875指出的那样,btw增加了额外的CPU负担.

运用

let ++i
Run Code Online (Sandbox Code Playgroud)

仅适用于我不是-1的特定情况,因为let i ++仅适用于i不为0.因此半解决方案.

我喜欢Unix,我不会有任何其他方式.


Arn*_*anc 9

如果let求值的最后一个参数0,则返回1(因此,非零状态):

从手册:

   let arg [arg ...]
Run Code Online (Sandbox Code Playgroud)

每个arg都是要计算的算术表达式.如果最后一个arg的计算结果为0,则返回1 ; 否则返回0.

i++iis 时求值为零0(因为它是一个后递增,所以i返回前一个值),所以let返回1,并且由于set -ebash存在.

以下是一些解决方案:

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
Run Code Online (Sandbox Code Playgroud)