How to use comparison operators in bash?

8,409

Solution 1

These operator are used in, e.g., (( ... )) and $(( ... )) (arithmetic evaluation and arithmetic expansion respectively):

if (( arg1 >= num1 )) && (( arg2 <= num2 )); then
    ...
fi

And also with let. The following is equivalent of the above:

if let "arg1 >= num1" && let "arg2 <= num2"; then
    ...
fi

See the section named "ARITHMETIC EVALUATION" in the Bash manual.

Solution 2

In bash specifically:

  • ((arg1 >= num1)) (inherited from ksh) does arithmetic comparison. arg1 and num1 here refer to the shell variables of the same name. Each variable is interpreted as an arithmetic expansion and the result substituted. Here if $arg1 is 010 and $num1 is 4+5, the result will be false (the ((...)) command will return with a non-zero exit status), because 010 is octal for 8 and 4+5 is 9.
  • (($arg1 >= $num1)): same as above except that $arg1 and $num1 are expanded before that whole arithmetic expression is evaluated. If $arg1 was (2 and $num1 was 2), the previous command would have failed because (2 and 2) are not valid expressions on their own. But here it would succeed because (2 >= 2) would be the arithmetic expression being evaluated. Generally, within arithmetic expressions, it's better to leave the $ out. Compare for instance a=2+2; echo "$((3 * $a))" with a=2+2; echo "$((3 * a))".
  • let "..." (also from ksh). Same as ((...)) except that it's parsed as a normal command, is less legible, is as little portable and you need to pay closer attention to quoting.
  • [ "$arg1" -ge "$num1" ]. That's standard and portable. Only decimal constants are supported. [ 010 -ge 9 ] is the same as [ 10 -ge 9 ].
  • [[ $arg1 -ge $num1 ]]. Also from ksh but with major differences. This time, $arg1 and $num1 are considered as arithmetic expressions and not just decimal constants. [[ 010 -ge 9 ]] returns false again.
  • [[ $arg1 < $num1 ]]. String comparison. That uses strcoll() to compare strings, so using the sorting algorithm in the locale. Note that while < and > use the sorting algorithm, =/== do byte-to-byte comparison, so there may be pairs of strings for which all of <, > and =/== return false. <= and >= are not supported.
  • [ "$arg1" "<" "$num1" ]. Non-standard. Same as above but using the [ command. < needs to be quoted so it's not taken as a redirection operator.
  • expr " $arg1" "<=" " $num1" > /dev/null (note the embedded spaces to force lexical comparison and avoid issues with strings looking like expr operators) or awk 'BEGIN{exit(!(""ARGV[1] <= ""ARGV[2]))}' "$arg1" "$num1" are the standard commands to do string comparison using strcoll().
Share:
8,409

Related videos on Youtube

MikeD
Author by

MikeD

BY DAY: C#, Powershell, and BASH, (etc.) in a Fortune 500 IT Department. BY NIGHT: Always learning FOR FUN: Guitar, Photography

Updated on September 18, 2022

Comments

  • MikeD
    MikeD almost 2 years

    How can I use <=, >=, >, and < in bash?

    Instead of:

    if [[ $arg1 -ge $num1 && $arg2 -le $num2 ]]; then
         ...
    fi
    

    Have something more like:

    if [[ $arg1 >= $num1 && $arg2 <= $num2 ]]; then
         ...
    fi