Why does bash evaluate comparison of numbers lexicographically not numerically?

感情迁移 提交于 2021-01-27 13:32:49

问题


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)"


回答1:


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.




回答2:


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


来源:https://stackoverflow.com/questions/58852972/why-does-bash-evaluate-comparison-of-numbers-lexicographically-not-numerically

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!