65

I am doing integer comparison in bash (trying to see if the user is running as root), and I found two different ways of doing it:

Double equals:

if [ $UID == 0 ]
then
fi

-eq

if [ $UID -eq 0 ]
then
fi

I understand that there's no >= or <= in bash, only -ge and -le, so why is there a == if there's a -eq?

Is there a difference in the way it compares both sides?

beatgammit
  • 7,453
  • 10
  • 31
  • 32

3 Answers3

80

== is a bash-specific alias for =, which performs a string (lexical) comparison instead of the -eq numeric comparison. (It's backwards from Perl: the word-style operators are numeric, the symbolic ones lexical.)

EightBitTony
  • 20,963
  • 4
  • 61
  • 62
geekosaur
  • 31,429
  • 5
  • 79
  • 58
  • Does that mean that if both sides are integers, it converts both sides to strings and then compares them? – beatgammit Jul 05 '11 at 17:30
  • 6
    More precisely it's the other way around: everything is a string, `-eq` tells `bash` to interpret the strings as integers (producing `0` without a warning if a string isn't numeric). – geekosaur Jul 05 '11 at 17:34
  • 20
    @tjameson To give an example: `[ 01 -eq 1 ]` but `[ 01 != 1 ]`. – Gilles 'SO- stop being evil' Jul 05 '11 at 20:54
  • 5
    Note that while `==` as a `[` operator is non-standard and should not be used, it is not _bash-specific_. It was introduced by ksh and is also supported by zsh (though the first `=` needs to be quoted), yash and the GNU `[` utility (and any such utilities implemented as ksh scripts on some systems) at least). – Stéphane Chazelas Jun 15 '15 at 10:52
  • @geekosaur I get a warning from bash v4.3.42 if my string isn't numeric: `$ if [ "hello" -eq 0 ]; then echo true; fi` _bash: [: hello: integer expression expected_ – Andrew Bainbridge Aug 25 '16 at 09:23
14

To elaborate on bollovan's answer...

There is no >= or <= comparison operator for strings. But you could use them with the ((...)) arithmetic command to compare integers.

You can also use the other string comparison operators (==, !=, <, >, but not =) to compare integers if you use them inside ((...)).

Examples

  • Both [[ 01 -eq 1 ]] and (( 01 == 1 )) do integer comparisons. Both are true.
  • Both [[ 01 == 1 ]] and [ 01 = 1 ] do string comparisons. Both are false.
  • Both (( 01 -eq 1 )) and (( 01 = 1 )) will return an error.

Note: The double bracket syntax [[...]] and the double parentheses syntax ((...)) are not supported by all shells.

toxalot
  • 1,025
  • 1
  • 9
  • 21
  • 1
    Note that (except for `mksh`/`zsh` (except in POSIX mode (though that's not a POSIX feature))), `(( 010 == 10 ))` would return false because `010` would be treated as an octal number (8 in decimal). – Stéphane Chazelas Jun 15 '15 at 11:02
  • Note that while most `test`/`[` implementations don't have `>=`/`<=` operators (`yash`'s `[` has though), `expr` has such operators, though it will do arithmetic comparison if the arguments are recognised as numbers (`expr 01 '>=' 1` returns true, `expr X01 '>=' X1` returns false). – Stéphane Chazelas Jun 15 '15 at 11:05
7

If you want to do integer comparison you will better use (( )), where you can also use >= etc.

Example:

if (( $UID == 0 )); then
   echo "You are root"
else
   echo "You are not root"
fi
tshepang
  • 64,472
  • 86
  • 223
  • 290
bollovan
  • 513
  • 5
  • 11