skip to Main Content

Could someone explain the following behavior of the “if” block of bash ?

I use the following simple code check if the first_value is less than the second_value

first_value=67
second_value=2

if [[  "${first_value}" < "${second_value}" ]];
then 
    echo "Yes"
else 
    echo "No"
fi

The issue is

If the second_value is 1,2,3,4,5,6,10,11,… the block will return “No”

But if the second_value is 7,8,9 the block will return “Yes” (must be “No”)

The fix is to use “-lt” instead of “<” but I want to understand such behavior of the “if” block.

The bash version is “GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)”

The OS is “CentOS Linux release 7.5.1804 (Core)”

2

Answers


  1. The reason for this behavior is the fact, that the [[ "${first_value}" < "${second_value}" ]] is actually lexicographic comparison, because of [[ exp ]] brackets.

    As the OP mentions in the question, the possible fix is to use -lt operator.

    In bash, you can use arithmetic context:

    if (( $first_value < $second_value ));
    then 
        echo "Yes"
    else 
        echo "No"
    fi
    

    or even simpler

    if (( first_value < second_value ));
    then 
        echo "Yes"
    else 
        echo "No"
    fi
    
    Login or Signup to reply.
  2. As for your question: First, an if block does not return anything. It just executes one set of statements or another ones, which in your case write something to stdout.

    Now to the explanation of the behaviour you have observed.

    The < operator in a [[ ... ]] expression does lexicographic comparison. For instance in

    [[ 67 < 7 ]]
    

    “67” is lexically smaller than “7”, and hence [[ …. ]] returns status code 0, which means that the if is executing the then part, which causes Yes to be printed.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search