Bash: double equals vs -eq

99,687

Solution 1

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

Solution 2

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.

Solution 3

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
Share:
99,687
zilitron
Author by

zilitron

I write lots of code for fun and pay. Go, Rust, and Javascript are my specialties, though I'm confident in Python, Java, C#, C++, and C, with passing interest in a few other languages.

Updated on September 18, 2022

Comments

  • zilitron
    zilitron almost 2 years

    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?

    • Gilles 'SO- stop being evil'
      Gilles 'SO- stop being evil' almost 13 years
      Note that spaces inside brackets are required: [ $UID -eq 0 ], not [ $UID -eq 0].
  • zilitron
    zilitron almost 13 years
    Does that mean that if both sides are integers, it converts both sides to strings and then compares them?
  • geekosaur
    geekosaur almost 13 years
    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).
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' almost 13 years
    @tjameson To give an example: [ 01 -eq 1 ] but [ 01 != 1 ].
  • Stéphane Chazelas
    Stéphane Chazelas about 9 years
    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
    Stéphane Chazelas about 9 years
    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
    Stéphane Chazelas about 9 years
    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
    Stéphane Chazelas about 9 years
    Or (( UID == 0 )) or (( ! UID )) for that matters. Note that ((...)) is non-standard (a ksh feature also supported by bash and zsh with variations).
  • Andrew Bainbridge
    Andrew Bainbridge almost 8 years
    @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
  • Admin
    Admin about 2 years
    @StéphaneChazelas Since UID is not boolean would ! UID not be more like UID != 0.
  • Admin
    Admin about 2 years
    @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,
  • Admin
    Admin about 2 years
    I just don't like using a boolean operator on an int.