Bash: double equals vs -eq
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
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, 2022Comments
-
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' almost 13 yearsNote that spaces inside brackets are required:
[ $UID -eq 0 ]
, not[ $UID -eq 0]
.
-
-
zilitron almost 13 yearsDoes that mean that if both sides are integers, it converts both sides to strings and then compares them?
-
geekosaur almost 13 yearsMore precisely it's the other way around: everything is a string,
-eq
tellsbash
to interpret the strings as integers (producing0
without a warning if a string isn't numeric). -
Gilles 'SO- stop being evil' almost 13 years@tjameson To give an example:
[ 01 -eq 1 ]
but[ 01 != 1 ]
. -
Stéphane Chazelas about 9 yearsNote 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 about 9 yearsNote that (except for
mksh
/zsh
(except in POSIX mode (though that's not a POSIX feature))),(( 010 == 10 ))
would return false because010
would be treated as an octal number (8 in decimal). -
Stéphane Chazelas about 9 yearsNote 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 about 9 yearsOr
(( UID == 0 ))
or(( ! UID ))
for that matters. Note that((...))
is non-standard (aksh
feature also supported bybash
andzsh
with variations). -
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 about 2 years@StéphaneChazelas Since UID is not boolean would
! UID
not be more likeUID != 0
. -
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 likeUID == 0
. There's no such thing as "boolean" in shell arithmetics, -
Admin about 2 yearsI just don't like using a boolean operator on an int.