the following script with debug option 'set -e -v' fails at the increment operator only when the variable has a prior value of zero.
#!/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, version 4.0.33(1)-release (x86_64-apple-darwin10) but also GNU bash, version 4.2.4(1)-release (x86_64-unknown-linux-gnu))
any ideas?
the answer to my question is not to use let (or shift, or...) but to use
when trying to check a bash script by setting 'exit on non-zero status code' with
The bash manual states that set -e has the effect of 'Exit immediately if a simple command exits with a non-zero status.'.
Unfortunately let (and shift and ...) return the result of the computation ('If the last arg evaluates to 0, let returns 1; 0 is returned otherwise'). So instead of a status code one gets a return value of some sort. And sometimes this return value will be zero and sometimes one depending on the computation. Therefore set -e will cause the script to exit depending on the result of your computation!!! and there is nothing to do about it unless either you don't use it ever or resort to
as pointed by arnaud576875 which btw adds extra CPU burden.
Using
works only for the specific case that i is not -1, as with let i++ which works only for when i is not 0. Therefore half-solutions.
I love Unix though, I wouldn't have it any other way.
Looking at the BASH manpage on the
set -e
:So, if any statement returns a non-zero exit code, the shell will exit.
Taking a look at the BASH manpage, on the
let
command:But wait! The answer to
i++
is a one and not a zero! It should have worked!Again, the answer is with the BASH manpage on the increment operator:
Okay, not so clear. Try this shell script:
Hmmm... that works as expected, and all I did was change
i++
to++i
in each line.The
i++
is a post-increment operator. That means, it incrementsi
after thelet
statement returns a value. Sincei
was zero before being incremented, thelet
statement returns a non-zero value.However, the
++i
is a pre-increment operator. That means it incrementsi
before returning the exit status. Sincei
is incremented to a1
, the exit status becomes a zero.I hope this makes sense.
If the last argument of
let
evaluates to0
, let returns1
(so, a non-zero status):i++
evaluates to zero wheni
is0
(because it's a post-increment, so the previous value ofi
is returned), solet
returns1
, and due toset -e
, bash exists.Here are some solutions: