Comparison Operators
Strings and numbers compare differently in bash. Mix them up and your script breaks silently.
Numeric Comparisons
Inside [ ] or [[ ]]:
| Operator | Meaning |
|---|---|
-eq | Equal |
-ne | Not equal |
-lt | Less than |
-le | Less than or equal |
-gt | Greater than |
-ge | Greater than or equal |
#!/bin/bash
count=5
if [[ "$count" -eq 5 ]]; then
echo "Count is exactly 5"
fi
if [[ "$count" -gt 3 ]]; then
echo "Count is greater than 3"
fi
if [[ "$count" -le 10 ]]; then
echo "Count is 10 or less"
fi
Don't Use < > for Numbers
< and > are for strings. For numbers, use -lt and -gt. This mistake causes subtle bugs.
Arithmetic Comparisons (( ))
Inside (( )), use normal math operators:
#!/bin/bash
x=10
y=20
if (( x < y )); then
echo "x is less than y"
fi
if (( x == 10 )); then
echo "x equals 10"
fi
if (( x >= 5 && x <= 15 )); then
echo "x is between 5 and 15"
fi
Use (( )) for Math
(( )) is cleaner for numeric comparisons. No quotes needed, normal operators work.
String Comparisons
| Operator | Meaning |
|---|---|
== or = | Equal |
!= | Not equal |
< | Less than (alphabetically) |
> | Greater than (alphabetically) |
-z | Is empty |
-n | Is not empty |
#!/bin/bash
name="Alice"
empty_var=""
if [[ "$name" == "Alice" ]]; then
echo "Hello, Alice!"
fi
if [[ "$name" != "Bob" ]]; then
echo "You're not Bob"
fi
if [[ -z "$empty_var" ]]; then
echo "Variable is empty"
fi
if [[ -n "$name" ]]; then
echo "Name has a value"
fi
String Comparison Gotcha
String "5" comes after "10" alphabetically (5 > 1).
Pattern Matching (Strings)
Double brackets support patterns:
#!/bin/bash
file="report.txt"
if [[ "$file" == *.txt ]]; then
echo "It's a text file"
fi
if [[ "$file" == report* ]]; then
echo "It's a report"
fi
# Case insensitive
shopt -s nocasematch
if [[ "$file" == REPORT.TXT ]]; then
echo "Matches case-insensitively"
fi
Regex Matching
#!/bin/bash
email="user@example.com"
if [[ "$email" =~ ^[A-Za-z0-9]+@[A-Za-z0-9]+\.[A-Za-z]+$ ]]; then
echo "Valid email format"
fi
phone="555-123-4567"
if [[ "$phone" =~ ^[0-9]{3}-[0-9]{3}-[0-9]{4}$ ]]; then
echo "Valid phone format"
fi
=~ does regex matching.
Comparison Summary
| Type | Numbers | Strings |
|---|---|---|
| Equal | -eq or == in (()) | == |
| Not equal | -ne | != |
| Less than | -lt or < in (()) | < |
| Greater than | -gt or > in (()) | > |
| Empty | - | -z |
| Not empty | - | -n |
Practical Examples
#!/bin/bash
# Check if enough arguments
if [[ $# -lt 2 ]]; then
echo "Usage: $0 <source> <dest>"
exit 1
fi
# Validate port number
port=$1
if (( port < 1 || port > 65535 )); then
echo "Invalid port: must be 1-65535"
exit 1
fi
# Check environment
if [[ -z "$DATABASE_URL" ]]; then
echo "DATABASE_URL not set"
exit 1
fi
Which operator correctly compares if x is greater than 10?
Quick Reference
| Numeric | String | Meaning |
|---|---|---|
-eq | == | Equal |
-ne | != | Not equal |
-lt | < | Less than |
-gt | > | Greater than |
-le | - | Less or equal |
-ge | - | Greater or equal |
| - | -z | Is empty |
| - | -n | Not empty |
Key Takeaways
- Use
-eq,-lt,-gtfor numbers in[[ ]] - Use
<,>,==for strings in[[ ]] - Use normal operators in
(( ))for math -zchecks if empty,-nchecks if not empty[[ $file == *.txt ]]for pattern matching[[ $str =~ regex ]]for regex matching
Next: loops - repeat actions with for loops.