Skip to content
Advertisement

Why decrement of variable inside loop returns no success status code?

I can’t understand why inside loop with condition of equal to 0 decrementing of variable returns non-zero status code (not success) if variable was decreased to 0?

If I use a different condition for the loop – for example – until [[ $RETR -eq 1 ]] it returns 0 status code after last decreasing, the same situation for while loop or if I use let for decreasing the variable, but decreasing by ((varr–)) returns a 0 status code.

+ RETR=3
+ [[ 3 -eq 0 ]]
+ WRONG_COMMAND
+ [[ 127 -ne 0 ]]
+ echo 'RETRIES = 3'
RETRIES = 3
+ echo 'STATUS before decrease = 0'
STATUS before decrease = 0
+ (( --RETR ))
+ echo 'STATUS AFTER decrease = 0'
STATUS AFTER decrease = 0
+ [[ 2 -eq 0 ]]
+ WRONG_COMMAND
+ [[ 127 -ne 0 ]]
+ echo 'RETRIES = 2'
RETRIES = 2
+ echo 'STATUS before decrease = 0'
STATUS before decrease = 0
+ (( --RETR ))
+ echo 'STATUS AFTER decrease = 0'
STATUS AFTER decrease = 0
+ [[ 1 -eq 0 ]]
+ WRONG_COMMAND
+ [[ 127 -ne 0 ]]
+ echo 'RETRIES = 1'
RETRIES = 1
+ echo 'STATUS before decrease = 0'
STATUS before decrease = 0
+ (( --RETR ))
+ echo 'STATUS AFTER decrease = 1'
STATUS AFTER decrease = 1
+ [[ 0 -eq 0 ]]
+ echo 0
0

The script:

#!/usr/bin/env bash

set -x

RETR=3

until [[ $RETR -eq 0 ]]; do
    WRONG_COMMAND 2>/dev/null
    if [[ $? -ne 0 ]]; then
        echo "RETRIES = $RETR"
        echo "STATUS before decrease = $?"
        ((--RETR))
        echo "STATUS AFTER decrease = $?"
    else
        RETR=0
    fi;
done;

echo $?

I expect it to returns 0 status code after the variable was decreased, but it always returns 1 if the loop condition consists of equal to 0 and the variable equals 0 after decreasing.

Advertisement

Answer

The exit status of ((...)) is 1 if the enclosed expression evaluates to 0, and is 1 otherwise.

When using the decrement operator, the value of the expression (and thus the exit status) depends on when the decrement occurs. With --RETR, the variable is decremented, and then the value of RETR is used. With RETR--, the value of RETR is used, then it is decremented.

For example:

$ x=1; ((x--)); echo $?  # Value of x-- is 1
0
$ x=1; ((--x)); echo $?  # Value of --x is 0
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement