bashspecial-variables

Why does adding a sleep to a bash script seem to break variable decrementing for certain named variables?


With the following bash script:

#!/bin/bash
let SECONDS=5

until [[ "$SECONDS" -le "1" ]]; do
    echo SECONDS $SECONDS
    (( SECONDS -= 1 ))

#    sleep 1
done

I am seeing strange behavior. Namely, that if I uncomment the sleep 1 the loop continues but the counter does not decrement, I see output like:

$./mvce.sh 
SECONDS 5
SECONDS 5
SECONDS 5
SECONDS 5
SECONDS 5
SECONDS 5
SECONDS 5

Removing that line results in the expected:

$./mvce.sh 
SECONDS 5
SECONDS 4
SECONDS 3
SECONDS 2

I'm not really sure why this is happening. I can rename the variable to something else and things work as expected so it seems that something about sleep breaks my SECONDS variable.

This was surprising, why does calling sleep override the SECONDS variable within my script?


Solution

  • SECONDS is reserved variable in shell. That's why you must always use lowercase or mixed case variables in your script and avoid using all uppercase variable names.

    #!/bin/bash
    let secs=5
    
    until [[ "$secs" -le "1" ]]; do
        echo SECONDS $secs
        (( secs -= 1 ))
    
       sleep 1
    done
    

    That gives expected output:

    SECONDS 5
    SECONDS 4
    SECONDS 3
    SECONDS 2
    

    Doumentation:

    SECONDS
    Each time this parameter is referenced, the number of seconds since shell invocation is returned. If a value is assigned to SECONDS, the value returned upon subsequent references is the number of seconds since the assignment plus the value assigned. If SECONDS is unset, it loses its special properties, even if it is subsequently reset.