Bash Comparison Operators: Equal, Not Equal, Greater Than

By 

•

Updated on

•

9 min read

Bash comparison operators used in shell conditionals

Most Bash scripts need to make a decision at some point: does the user input match the expected value, or is the disk usage over the limit? You answer these questions with comparison operators. A comparison operator compares two values and returns true or false, and you will use them with if, elif, while, and case statements.

Bash has separate operators for numbers and for strings, and using the wrong one is a common source of bugs. This article explains how to compare integers, strings, and floating-point numbers in Bash, including equal, not equal, and greater-than checks.

Key Points

  • Bash uses different operators for comparing integers and for comparing strings.
  • Comparison operators can be used with single brackets [ ] (POSIX test), double brackets [[ ]] (Bash-specific, safer and more powerful), and double parentheses (( )) (arithmetic context).
  • Bash variables are untyped. They are treated as integer or string depending on the context.
  • Bash does not support floating-point operations. To compare floating point numbers, use an external tool such as bc or awk .

Comparing Integers

To compare integers, you can use test operators with brackets or arithmetic operators with double parentheses.

Integer Comparison Operators

OperatorDescription
-eqEqual to
-neNot equal to
-gtGreater than
-geGreater than or equal to
-ltLess than
-leLess than or equal to

Equal To Operator

The -eq operator checks if two integers are equal and returns true if they are:

sh
#!/bin/bash

NUM1=5
NUM2=5

if [ "$NUM1" -eq "$NUM2" ]; then
    echo "Numbers are equal."
else
    echo "Numbers are not equal."
fi
output
Numbers are equal.

Not Equal To Operator

The -ne operator returns true if two integers are not equal:

sh
#!/bin/bash

NUM1=5
NUM2=10

if [ "$NUM1" -ne "$NUM2" ]; then
    echo "Numbers are not equal."
else
    echo "Numbers are equal."
fi
output
Numbers are not equal.

The -ne operator works only with integers. To check if two strings are not equal, use != as shown in the string section .

Greater Than Operator

The -gt operator checks if the first integer is greater than the second and returns true if it is:

sh
#!/bin/bash

NUM1=10
NUM2=5

if [ "$NUM1" -gt "$NUM2" ]; then
    echo "$NUM1 is greater than $NUM2."
fi
output
10 is greater than 5.

Greater Than Or Equal Operator

The -ge operator returns true if the first integer is greater than or equal to the second:

sh
#!/bin/bash

NUM1=10
NUM2=10

if [ "$NUM1" -ge "$NUM2" ]; then
    echo "$NUM1 is greater than or equal to $NUM2."
fi
output
10 is greater than or equal to 10.

Less Than Operator

The -lt operator returns true if the first integer is less than the second:

sh
#!/bin/bash

NUM1=5
NUM2=10

if [ "$NUM1" -lt "$NUM2" ]; then
    echo "$NUM1 is less than $NUM2."
fi
output
5 is less than 10.

Less Than Or Equal Operator

The -le operator returns true if the first integer is less than or equal to the second:

sh
#!/bin/bash

NUM1=5
NUM2=5

if [ "$NUM1" -le "$NUM2" ]; then
    echo "$NUM1 is less than or equal to $NUM2."
fi
output
5 is less than or equal to 5.

Using Arithmetic Operators

You can also compare integers using arithmetic operators inside double parentheses (( )):

OperatorDescription
==Equal to
!=Not equal to
>Greater than
>=Greater than or equal to
<Less than
<=Less than or equal to
sh
#!/bin/bash

NUM1=10
NUM2=5

if (( NUM1 > NUM2 )); then
    echo "$NUM1 is greater than $NUM2."
fi
output
10 is greater than 5.
Tip
When using (( )), you do not need to add $ before variable names.

Comparing Strings

String comparison operators check whether strings are equal or not equal, or compare them lexicographically (alphabetically). For case-insensitive matching and glob patterns, see our guide on comparing strings in Bash .

String Comparison Operators

OperatorDescription
= or ==Equal to
!=Not equal to
<Less than (lexicographically)
>Greater than (lexicographically)
-zString is empty
-nString is not empty
=~Regex match

Check if Two Strings are Equal

Use the = operator with single brackets or == with double brackets (recommended):

sh
#!/bin/bash

VAR1="Linuxize"
VAR2="Linuxize"

if [ "$VAR1" = "$VAR2" ]; then
    echo "Strings are equal."
else
    echo "Strings are not equal."
fi
output
Strings are equal.

Here is how to use double brackets with user input. IFS= preserves leading and trailing whitespace, and read -r keeps backslashes literal:

sh
#!/bin/bash

IFS= read -r -p "Enter first string: " VAR1
IFS= read -r -p "Enter second string: " VAR2

if [[ "$VAR1" == "$VAR2" ]]; then
    echo "Strings are equal."
else
    echo "Strings are not equal."
fi
output
Enter first string: Linuxize
Enter second string: Ubuntu
Strings are not equal.

You can also use logical operators:

sh
[[ "string1" == "string2" ]] && echo "Equal" || echo "Not equal"
output
Not equal

Check if Two Strings are Not Equal

The != operator returns true when two strings are different. It works with both single and double brackets:

sh
#!/bin/bash

ANSWER="yes"

if [[ "$ANSWER" != "no" ]]; then
    echo "Continuing..."
fi
output
Continuing...

The script prints the message because yes is not equal to no.

You can also negate a whole test with !. The following condition is true when the strings differ, the same as using !=:

sh
if ! [[ "$ANSWER" == "no" ]]; then
    echo "Continuing..."
fi

Check if a String Contains a Substring

Use the * wildcard to match patterns in strings:

sh
#!/bin/bash

VAR='GNU/Linux is an operating system'
if [[ $VAR == *"Linux"* ]]; then
  echo "The string contains Linux."
fi
output
The string contains Linux.

You can also use the =~ operator for regular expression matching:

sh
#!/bin/bash

VAR='GNU/Linux is an operating system'
if [[ $VAR =~ .*Linux.* ]]; then
  echo "The string contains Linux."
fi

Check if a String is Empty

Use -z to check if a string is empty, and -n to check if it is not empty:

sh
#!/bin/bash

VAR=''
if [[ -z $VAR ]]; then
  echo "String is empty."
fi
output
String is empty.
sh
#!/bin/bash

VAR='Linuxize'
if [[ -n $VAR ]]; then
  echo "String is not empty."
fi
output
String is not empty.

Comparing Strings with the Case Operator

You can also use the case statement to compare strings:

sh
#!/bin/bash

VAR="Arch Linux"

case $VAR in
  "Arch Linux")
    echo "Arch matched"
    ;;
  Fedora | CentOS)
    echo "Red Hat based"
    ;;
esac
output
Arch matched

The case statement is useful when you need to match a variable against several patterns.

Lexicographic Comparison

Lexicographic comparison compares strings alphabetically, character by character:

sh
#!/bin/bash

VAR1="Linuxize"
VAR2="Ubuntu"

if [[ "$VAR1" > "$VAR2" ]]; then
    echo "${VAR1} is lexicographically greater than ${VAR2}."
elif [[ "$VAR1" < "$VAR2" ]]; then
    echo "${VAR2} is lexicographically greater than ${VAR1}."
else
    echo "Strings are equal"
fi
output
Ubuntu is lexicographically greater than Linuxize.

Comparing Floating-Point Numbers

Bash cannot compare floating-point numbers directly, but we can use utilities like bc or awk to make the comparison.

Using bc

sh
NUM1=3.14
NUM2=2.71

if (( $(echo "$NUM1 > $NUM2" | bc -l) )); then
    echo "$NUM1 is greater"
fi

Using awk

sh
awk 'BEGIN { if (3.14 > 2.71) print "3.14 is greater" }'

Important Notes

  • Use double quotes around variable expansions inside [ ] to prevent word splitting and globbing. Inside [[ ]], these expansions do not undergo word splitting or globbing.
  • Inside [[ ]], quoting the right-hand operand of ==, !=, or =~ makes it literal. Leave intended pattern or regex syntax unquoted.
  • With [ ] and [[ ]], put a space between the operator and the operands.
  • Use = with single brackets [ ] and == with double brackets [[ ]].
  • Inside double brackets, < and > do not need to be escaped.
  • Inside single brackets, < and > must be escaped: \< and \>.

Quick Reference

For a printable quick reference, see the Bash cheatsheet .

OperatorContextDescription
-eq[ ] [[ ]]Integer equal to
-ne[ ] [[ ]]Integer not equal to
-gt[ ] [[ ]]Integer greater than
-ge[ ] [[ ]]Integer greater than or equal to
-lt[ ] [[ ]]Integer less than
-le[ ] [[ ]]Integer less than or equal to
== != > <(( ))Arithmetic comparison
= or ==[ ] [[ ]]String equal to
!=[ ] [[ ]]String not equal to
< >[[ ]]String lexicographic comparison
-z[ ] [[ ]]String is empty
-n[ ] [[ ]]String is not empty
=~[[ ]]String matches regex

FAQ

What is the difference between [ ] and [[ ]] in Bash?
[ ] is the POSIX test command and works in any POSIX-compatible shell. [[ ]] is a Bash-specific keyword that is safer and more powerful; it supports regex matching with =~, does not require quoting variables to prevent word splitting, and allows < and > without escaping. Prefer [[ ]] in Bash scripts.

Why does -eq not work for strings?
-eq performs an integer comparison. With [ ], non-numeric operands cause an integer expression expected error. With [[ ]], operands are evaluated as arithmetic expressions, so names of unset variables can evaluate to zero and make different strings appear equal. Use [ "$a" = "$b" ] or [[ "$a" == "$b" ]] to compare strings literally.

Can I compare numbers with == inside single brackets?
No. Inside [ ], == is a string comparison, so [ 10 == 10 ] works but [ 10 == 9+1 ] does not, because it compares the literal strings 10 and 9+1. Use -eq for integer comparison in [ ], or use (( 10 == 9+1 )) for arithmetic evaluation.

How do I check if a variable is greater than zero?
Use [[ $VAR -gt 0 ]] or (( VAR > 0 )). Both are equivalent in Bash.

How do I write “not equal” in Bash?
Use -ne for integers and != for strings. For example, [ "$a" -ne "$b" ] compares numbers, while [[ "$a" != "$b" ]] compares strings. Inside (( )), use != for arithmetic not-equal.

Conclusion

Use -eq, -ne, -gt, -ge, -lt, and -le for integer comparisons in brackets, or arithmetic operators inside (( )). For literal string comparisons, use [[ ]] with a quoted right-hand operand.

Tags

Linuxize Weekly Newsletter

A quick weekly roundup of new tutorials, news, and tips.

About the authors

Dejan Panovski

Dejan Panovski

Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 1000+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.

View author page