Web Analytics

Comparison Operators

Beginner ~25 min read

Comparison operators are the foundation of conditional logic in Bash. They let you compare numbers, strings, and patterns to make decisions in your scripts. You'll learn about the [[ ]] test construct, numeric comparison flags, string operators, and powerful pattern matching with regex!

Integer Comparison Operators

Bash provides two main ways to compare integers: using (( )) with C-style operators, or using [[ ]] with flag-based operators. Both are widely used.

Output
Click Run to execute your code

C-Style Operators in (( ))

Operator Description Example
== Equal to ((a == b))
!= Not equal to ((a != b))
< Less than ((a < b))
> Greater than ((a > b))
<= Less than or equal ((a <= b))
>= Greater than or equal ((a >= b))

Flag-Based Operators in [[ ]] or [ ]

Operator Description Example
-eq Equal to [[ $a -eq $b ]]
-ne Not equal to [[ $a -ne $b ]]
-lt Less than [[ $a -lt $b ]]
-gt Greater than [[ $a -gt $b ]]
-le Less than or equal [[ $a -le $b ]]
-ge Greater than or equal [[ $a -ge $b ]]
Key Point: Use (( )) for arithmetic comparisons (looks cleaner, supports C-style operators). Use [[ ]] when mixing with string tests or when you need the flag-based operators for POSIX compatibility.

String Comparison Operators

String comparisons check text values. Always quote your variables inside [[ ]] to handle empty strings and spaces correctly!

Output
Click Run to execute your code
Operator Description Example
== or = String equality [[ "$a" == "$b" ]]
!= String inequality [[ "$a" != "$b" ]]
< Less than (lexicographic) [[ "$a" < "$b" ]]
> Greater than (lexicographic) [[ "$a" > "$b" ]]
-z String is empty (zero length) [[ -z "$str" ]]
-n String is not empty [[ -n "$str" ]]
Pro Tip: Always quote variables in string comparisons: [[ "$var" == "text" ]]. This prevents errors when variables are empty or contain spaces. Inside [[ ]], word splitting doesn't occur, but quoting is still a good habit!

Pattern Matching and Regex

The [[ ]] construct supports glob-style pattern matching with == and full regex matching with =~. These are powerful tools for string validation!

Output
Click Run to execute your code
Pattern Matching Types:
  • Glob patterns with ==: Use * (any chars), ? (one char), [...] (character class)
  • Regex patterns with =~: Full extended regex support
  • BASH_REMATCH: Array containing regex matches (index 0 = full match, 1+ = capture groups)
Caution: When using =~ for regex, do NOT quote the pattern! Quoting turns it into a literal string match. Write [[ $str =~ ^[0-9]+$ ]] not [[ $str =~ "^[0-9]+$" ]].

The test Command and [ ]

The test command and [ ] are the POSIX-compliant, portable way to do comparisons. They work in any shell, not just Bash.

# test command and [ ] are equivalent
test 5 -eq 5 && echo "Equal"
[ 5 -eq 5 ] && echo "Equal"

# String tests
test -n "hello" && echo "Not empty"
[ -z "" ] && echo "Empty"

# Combining with && and ||
[ "$USER" = "root" ] && echo "You are root" || echo "Not root"

# IMPORTANT: Spaces are required!
# [ "$a"="$b" ]   # WRONG - no spaces
# [ "$a" = "$b" ] # CORRECT - spaces around =
Pro Tip: Prefer [[ ]] over [ ] in Bash scripts. It's more powerful (supports regex, pattern matching), safer (no word splitting), and doesn't require escaping < and >. Use [ ] only when writing portable POSIX scripts.

Common Mistakes

1. Using = vs == for strings

# In [ ], use single =
[ "$str" = "hello" ]   # Correct for [ ]

# In [[ ]], prefer ==
[[ "$str" == "hello" ]]  # Preferred for [[ ]]

# Don't use -eq for strings!
[[ "$str" -eq "hello" ]]  # Wrong! -eq is for numbers

2. Missing spaces in [ ]

# Wrong - no spaces
[$a -eq $b]      # Error: command not found
[ $a -eq$b ]     # Error

# Correct - spaces required
[ $a -eq $b ]    # Works
[[ $a -eq $b ]]  # Works

3. Quoting regex patterns

# Wrong - pattern is quoted, treated as literal
[[ "test123" =~ "^[a-z]+[0-9]+$" ]]  # Fails

# Correct - don't quote regex patterns
[[ "test123" =~ ^[a-z]+[0-9]+$ ]]    # Works

4. Comparing numbers as strings

# Problematic - string comparison
[[ "10" > "9" ]]    # False! '10' < '9' lexicographically

# Correct - numeric comparison
[[ 10 -gt 9 ]]      # True
((10 > 9))          # True

Exercise: Input Validation Script

Task: Create a script that validates different types of input!

Requirements:

  • Check if a number is within a range (1-100)
  • Validate that a string is not empty
  • Check if a filename has a specific extension (.sh)
  • Use regex to validate a simple email format
Show Solution
#!/bin/bash
# Input Validation Script

echo "=== Input Validation ==="
echo ""

# Number range check
number=50
echo "Checking number: $number"
if ((number >= 1 && number <= 100)); then
    echo "  Valid: $number is between 1 and 100"
else
    echo "  Invalid: Out of range"
fi
echo ""

# String not empty
username="alice"
echo "Checking username: '$username'"
if [[ -n "$username" ]]; then
    echo "  Valid: Username is not empty"
else
    echo "  Invalid: Username is empty"
fi
echo ""

# Filename extension
filename="script.sh"
echo "Checking filename: '$filename'"
if [[ "$filename" == *.sh ]]; then
    echo "  Valid: File has .sh extension"
else
    echo "  Invalid: Not a shell script"
fi
echo ""

# Email validation (simple regex)
email="[email protected]"
echo "Checking email: '$email'"
if [[ "$email" =~ ^[a-zA-Z0-9]+@[a-zA-Z0-9]+\.[a-zA-Z]+$ ]]; then
    echo "  Valid: Looks like an email"
else
    echo "  Invalid: Not a valid email format"
fi

Summary

  • Integer Comparisons: Use (( )) with ==, !=, <, >, <=, >= or [[ ]] with -eq, -ne, -lt, -gt, -le, -ge
  • String Comparisons: Use ==, !=, <, > inside [[ ]]; check empty with -z and -n
  • Pattern Matching: Use == with glob patterns (*, ?, [...])
  • Regex Matching: Use =~ with unquoted regex; access matches via BASH_REMATCH
  • [[ ]] vs [ ]: Prefer [[ ]] for Bash; use [ ] for POSIX portability
  • Always Quote: Quote variables in comparisons to handle empty values safely

What's Next?

Now that you can compare values, let's learn about Logical Operators. You'll discover how to combine conditions using AND (&&), OR (||), and NOT (!) to build complex conditional logic in your scripts!