63

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

78

== 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
  • 19
    @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 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 at 13:56
  • I just don't like using a boolean operator on an int.
    – Jeter-work
    Apr 28 at 14:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.