DEAR PEOPLE FROM THE FUTURE: Here's what we've figured out so far...

Welcome! This is a Q&A website for computer programmers and users alike, focused on helping fellow programmers and users. Read more

What are you stuck on? Ask a question and hopefully somebody will be able to help you out!
+1 vote

I've been reading this:

https://mywiki.wooledge.org/BashPitfalls#cmd1_.26.26_cmd2_.7C.7C_cmd3

I can replicate this in both bash and ksh.

i= ; ((i++)) ; echo $?

i=0 ; ((i++)) ; echo $?

If incrementing i represents an example of an arbitrary cmd2, how do we know if anything actually works or fails in bash?

by
edited by

1 Answer

+1 vote
 
Best answer

In Bash if you don't explicitly set an exit code, the exit code of the script will be the exit code of the last command that ran. So it's possible to have a command that failed but the script returns 0 (success) because another command ran successfully after the one that failed. If you add another command to your example for instance, like this i=0 ; ((i++)) ; echo ; echo $? it will return zero. The return value of (( is (according to the manual): "If the value of the expression is non-zero, the return status is 0; otherwise the return status is 1." Your example returns 1 because i++ is evaluated later; ++i will return 0.
The expression (( ... )) is being evaluated arithmetically and does not return an success/error code. This is what the manual has to say about arithmetic: "The operators and their precedence, associativity, and values are the same as in the C language." In C a zero value is considered false whereas anything else is true. In Bash is the reverse, ie. zero is considered "success" whereas anything else is considered an error exit code.
To answer your last question, I think the only way to know if everything works is either to exit the script prematurely with exit <error_code> or check the exit code after every command with if [ $? -ne 0 ]; then. Or in this case you can use arithmetic expansion i=$((i+1)); this will return zero, and in case of error it will return non-zero for example i=$((i/0)). Alternatively in Bash you cal also add set -e at the top of the script and it will automatically exit as soon as any command returns a non-zero exit code (this does not seem to work with zsh though).

by
selected by
0

Thanks! That explanation and specific links to the arithmetic expression and shell-arithmetic gave me what I needed. I've gotten lost in that manual before...

Contributions licensed under CC0
...