Bash -Eq and ==, What's the Diff

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:

  1. 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 write

    if [ -f "$file" ]

    to correctly handle empty strings or file names with spaces in them. With [[ the quotes are unnecessary:

    if [[ -f $file ]]
  2. 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.

  3. It has a wonderful =~ operator for doing regular expression matches. With [ you might write

    if [ "$answer" = y -o "$answer" = yes ]

    With [[ you can write this as

    if [[ $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.

  4. 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



Leave a reply



Submit