5

Incrementing a variable var works in bash when enclosed in double parentheses like (( var++ )). But I have found that it fails if variable is set to 0 beforehand like var=0.

$ a=0
$ ((a++)) && echo "command succeeded" || echo "command failed"
command failed

$ a=1
$ ((a++)) && echo "command succeeded" || echo "command failed"
command succeeded

Can someone explain this behavior?

Environment:

I am using gnome-terminal on Ubuntu Desktop 18.04.5 LTS.

4
  • 4
    I think you should not really on the exit status of (( to know if the command was working.. >> "If the result of the expression is 0, the exit status code returned will be 1 or “false”, while the exit status code returned by a non-zero value expression will be 0 or “true”." (via)
    – pLumo
    Dec 8 '21 at 15:56
  • 1
    Sidenote: there's more than one way to increment a variable in Bash. Probably the most idiomatic is to explicitly make it an integer first: declare -i a=0 then a+=1.
    – wjandrea
    Dec 9 '21 at 0:16
  • @pLumo, it's not the exit status that's wrong, but the users' assumptions (yours, too). It works exactly like post-increment is defined, and exactly like it does in e.g. C. Though you're right in that you can't use the exit status of (( .. )) to see if it worked, since a syntax error also makes it exit with status 1. (and not e.g. 2, like [ and [[ do)
    – ilkkachu
    Dec 9 '21 at 10:05
  • @pLumo, exit status code is of concern to me because script is using trap ... ERR and this line provokes it. I have avoided this scenario, for now, by using pre-increment as my base value is 0 for var. But this solution is specific to my use case. Maybe I should search for a way to bypass trap for such/selected statements. Dec 11 '21 at 7:48
10

With credit from here: https://unix.stackexchange.com/questions/146773/why-bash-increment-n-0n-return-error

The return value of (( expression )) does not indicate an error status, but, from the bash manpage:

((expression)) The expression is evaluated according to the rules described below under ARITHMETIC EVALUATION. If the value of the expression is non-zero, the return status is 0; otherwise the return status is 1. This is exactly equivalent to let "expression".

In ((a++))you are doing a post increment. The value of a is 0 so 1 is returned, after that, it is incremented.

Compare

$ unset a
$ ((a++)) ; echo Exitcode: $? a: $a
Exitcode: 1 a: 1

versus

$ unset a
$ ((++a)) ; echo Exitcode: $? a: $a
Exitcode: 0 a: 1

A pre-increment, so a has become 1 and 0 is returned.

1
  • Technically, the increment occurs before the return; however, the returned value is the value taken before the increment.
    – wizzwizz4
    Dec 9 '21 at 18:06
5

This works for me (in bash in Ubuntu),

$ a=0
$ echo $((a++))
0
$ echo $((a++))
1
$ echo $((a++))
2
$ echo $((a++))
3
$ echo $a
4

Notice the difference with

$ a=0
$ echo $((++a))
1
$ echo $((++a))
2
$ echo $((++a))
3
$ echo $a
3
3
  • 2
    check echo $?.
    – pLumo
    Dec 8 '21 at 15:48
  • 2
    @pLumo, echo $((a++)) prints before update, echo $((++a)) prints after update.
    – sudodus
    Dec 8 '21 at 15:51
  • Arithmetic expansion does not emit an exit status does not see the connection?
    – bac0n
    Dec 8 '21 at 17:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.