Search code examples
bashshellstring-comparisoncomparison-operators

Binary operator compatibility for shell


I can't help noticing there are so many shell codes using comparison operators as test command's arguments, not with signs.

For example, to test if no arguments are received in shell using test:

if test $# -eq 0
then
    echo "No arguments received"
fi

Why can't we replace -eq with more, say, traditional, intuitive, familiar, universal, and, readable sign with ==? So that we have the following:

if test $# == 0
then
    echo "No arguments received"
fi

The same goes with other comparison operators < <= => >.

I'm assuming there must be some technical reasons behind this (perhaps compatibility issue?) to favor -eq format over ==, but I'm not aware of them.


Solution

  • First of all, use $#, not $@.

    The technical reason for the difference is that the operators define how the operands are interpretted.

    For <, = and >, the operands are considered strings. This means that 10 < 2 because 1-something comes before 2-something in the alphabet, and 1 != 01 because the strings are of different lengths.

    For -eq, -gt, -lt, the operands are considered integers. This means that 2 -lt 10 because the number 2 is smaller than the number 10, and 1 -eq 01 because these are both numerically equivalent ways of writing 1.