Shell equality operators (=, ==, -eq)
=
and ==
are for string comparisons-eq
is for numeric comparisons-eq
is in the same family as -lt
, -le
, -gt
, -ge
, and -ne
==
is specific to bash (not present in sh (Bourne shell), ...). Using POSIX =
is preferred for compatibility. In bash the two are equivalent, and in sh =
is the only one that will work.
$ a=foo
$ [ "$a" = foo ]; echo "$?" # POSIX sh
0
$ [ "$a" == foo ]; echo "$?" # bash-specific
0
$ [ "$a" -eq foo ]; echo "$?" # wrong
-bash: [: foo: integer expression expected
2
(Note: make sure to quote the variable expansions. Do not leave out the double-quotes above.)
If you're writing a #!/bin/bash
script then I recommend using [[
instead. The double square-brackets [[...]]
form has more features, a more natural syntax, and fewer gotchas that will trip you up. For example, double quotes are no longer required around $a
:
$ [[ $a == foo ]]; echo "$?" # bash-specific
0
See also:
- What's the difference between [ and [[ in Bash?
Bash -eq and ==, what's the diff?
-eq
is an arithmetic test.
You are comparing strings.
From help test
:
Other operators:
arg1 OP arg2 Arithmetic tests. OP is one of -eq, -ne,
-lt, -le, -gt, or -ge.
When you use [[
and use -eq
as the operator, the shell attempts to evaluate the LHS and RHS. The following example would explain it:
$ foo=something
+ foo=something
$ bar=other
+ bar=other
$ [[ $foo -eq $bar ]] && echo y
+ [[ something -eq other ]]
+ echo y
y
$ something=42
+ something=42
$ [[ $foo -eq $bar ]] && echo y
+ [[ something -eq other ]]
$ other=42
+ other=42
$ [[ $foo -eq $bar ]] && echo y
+ [[ something -eq other ]]
+ echo y
y
What is the difference between IF [ condition ] & [[ condition ]] , -eq and == in bash
In bash, numeric comparison is handled differently than string comparison
For numbers,
$var1 -eq $var2 // =
$var1 -gt $var2 // >
$var1 -ge $var2 // >=
$var1 -lt $var2 // <
$var1 -le $var2 // <=
$var1 -ne $var2 // !=
For strings
$str1 = $str2 // they are equal
str1 != str2 // not equal
str // Returns True if str is not null.
-n str // Returns True if the length of str is greater than zero.
-z str // Returns True if the length of str is equal to zero.
Note that == is the same as =
Also note that the == operates differently in a double bracket comparison (this is where your [ condition ] vs [[ condition ]] question comes in) when doing pattern matching. These comparisons/operators all all explained at http://www.tldp.org/LDP/abs/html/comparison-ops.html
Comparison operators Bash
You can just use test
, without if
:
x=1
y=1
[ $"{x}" -eq $"{y}" ] && echo "True" || echo "False"
Here, if x
equal y
, logical AND (&&
) works, and script echo "True".
If x
not equal, logical OR (
||`) works, script echo "False".
Upd. by @randomir advice, another available solutions:
(( $"x" == $"y" )) && echo True || echo False
Or:
[[ $"a" == $"y" ]] && echo True || echo False
When/how to use == or -eq operator in test?
From help test
:
[...]
STRING1 = STRING2
True if the strings are equal.
[...]
arg1 OP arg2 Arithmetic tests. OP is one of -eq, -ne,
-lt, -le, -gt, or -ge.
But in any case, each part of the condition is a separate argument to [
.
if [ "$arg" -eq 0 ]; then
if [ "$arg" = 0 ]; then
bash string equality
There's no difference, ==
is a synonym for =
(for the C/C++ people, I assume). See here, for example.
You could double-check just to be really sure or just for your interest by looking at the bash source code, should be somewhere in the parsing code there, but I couldn't find it straightaway.
What's the difference between [ and [[ in Bash?
[[
is bash's improvement to the [
command. It has several enhancements that make it a better choice if you write scripts that target bash. My favorites are:
It is a syntactical feature of the shell, so it has some special behavior that
[
doesn't have. You no longer have to quote variables like mad because[[
handles empty strings and strings with whitespace more intuitively. For example, with[
you have to writeif [ -f "$file" ]
to correctly handle empty strings or file names with spaces in them. With
[[
the quotes are unnecessary:if [[ -f $file ]]
Because it is a syntactical feature, it lets you use
&&
and||
operators for boolean tests and<
and>
for string comparisons.[
cannot do this because it is a regular command and&&
,||
,<
, and>
are not passed to regular commands as command-line arguments.It has a wonderful
=~
operator for doing regular expression matches. With[
you might writeif [ "$answer" = y -o "$answer" = yes ]
With
[[
you can write this asif [[ $answer =~ ^y(es)?$ ]]
It even lets you access the captured groups which it stores in
BASH_REMATCH
. For instance,${BASH_REMATCH[1]}
would be "es" if you typed a full "yes" above.You get pattern matching aka globbing for free. Maybe you're less strict about how to type yes. Maybe you're okay if the user types y-anything. Got you covered:
if [[ $ANSWER = y* ]]
Keep in mind that it is a bash extension, so if you are writing sh-compatible scripts then you need to stick with [
. Make sure you have the #!/bin/bash
shebang line for your script if you use double brackets.
See also
- Bash FAQ - "What is the difference between test, [ and [[ ?"
- Bash Practices - Bash Tests
- Server Fault - What is the difference between double and single brackets in bash?
Related Topics
How to Scale Ejabberd Server MAChine on Centos to Handle 200 K Connections
How to Prevent an X Window from Receiving User Input
How to Increase Openfabrics Memory Limit for Torque Jobs
Linking to Modules Folder Gives Undefined Reference
Filter a Content File to Table
Focas Fwlib32 Cnc Library on Linux Platform
Use Grep to Find the Words That Have Two 'S' Separated by a Space
Bash-Script Error 0=1: Command Not Found
Bash - How to Match Files Names to Use in Loop
Specify Git Tool to Use in Multi-Os Agent Jenkins Environment for Declarative Pipeline
How to Suspend and Resume a Sequence of Commands in Bash
Perl - Replace Every Nth (And Multiples) Occurrences of a Character with Another Character
Get and Use a Password with Special Characters in Bash Shell
How to Read Input from the Terminal Using /Dev/Stdin and Read.Csv()
How to Add Text at the Beginning of Specific Lines Using Sed
Read Data from Proc/Sys/Kernel/
How to Stop Apache from Listing the Contents of My User Directories