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
  • 5
    Note that spaces inside brackets are required: [ $UID -eq 0 ], not [ $UID -eq 0]. Commented 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? Commented 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). Commented Jul 5, 2011 at 17:34
  • 20
    @tjameson To give an example: [ 01 -eq 1 ] but [ 01 != 1 ]. Commented 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). Commented 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 Commented 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). Commented 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). Commented 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). Commented Jun 15, 2015 at 11:09
  • @StéphaneChazelas Since UID is not boolean would ! UID not be more like UID != 0. Commented 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, Commented Apr 28, 2022 at 13:56
  • I just don't like using a boolean operator on an int. Commented Apr 28, 2022 at 14:05

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.