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?

1
  • 4
    Note that spaces inside brackets are required: [ $UID -eq 0 ], not [ $UID -eq 0]. Jul 5, 2011 at 20:54

3 Answers 3

81

== 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.)

5
  • Does that mean that if both sides are integers, it converts both sides to strings and then compares them?
    – beatgammit
    Jul 5, 2011 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 5, 2011 at 17:34
  • 20
    @tjameson To give an example: [ 01 -eq 1 ] but [ 01 != 1 ]. Jul 5, 2011 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). Jun 15, 2015 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 Aug 25, 2016 at 9: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.

2
  • 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). Jun 15, 2015 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). Jun 15, 2015 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
4
  • 1
    Or (( UID == 0 )) or (( ! UID )) for that matters. Note that ((...)) is non-standard (a ksh feature also supported by bash and zsh with variations). Jun 15, 2015 at 11:09
  • @StéphaneChazelas Since UID is not boolean would ! UID not be more like UID != 0.
    – Jeter-work
    Apr 28, 2022 at 13:16
  • @Jeter-work, it's like in C / awk / perl..., ! UID evaluates to 1 if UID is 0 or to 0 otherwise, so it's exactly like UID == 0. There's no such thing as "boolean" in shell arithmetics, Apr 28, 2022 at 13:56
  • I just don't like using a boolean operator on an int.
    – Jeter-work
    Apr 28, 2022 at 14:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .