Comparison Operators
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.
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 ]] |
(( )) 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!
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" ]] |
[[ "$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!
Click Run to execute your code
- 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)
=~ 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 =
[[ ]] 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-zand-n - Pattern Matching: Use
==with glob patterns (*, ?, [...]) - Regex Matching: Use
=~with unquoted regex; access matches viaBASH_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!
Enjoying these tutorials?