Comparison Operators

Strings and numbers compare differently in bash. Mix them up and your script breaks silently.

Numeric Comparisons

Inside [ ] or [[ ]]:

OperatorMeaning
-eqEqual
-neNot equal
-ltLess than
-leLess than or equal
-gtGreater than
-geGreater than or equal
hljs bash
#!/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:

hljs bash
#!/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

OperatorMeaning
== or =Equal
!=Not equal
<Less than (alphabetically)
>Greater than (alphabetically)
-zIs empty
-nIs not empty
hljs bash
#!/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

Terminal
$# This compares as STRINGS:
$[[ 5 > 10 ]] && echo yes
yes (wrong! 5 > 10 alphabetically)
$
$# This compares as NUMBERS:
$[[ 5 -gt 10 ]] && echo yes
(nothing - correct!)

String "5" comes after "10" alphabetically (5 > 1).

Pattern Matching (Strings)

Double brackets support patterns:

hljs bash
#!/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

hljs bash
#!/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

TypeNumbersStrings
Equal-eq or == in (())==
Not equal-ne!=
Less than-lt or < in (())<
Greater than-gt or > in (())>
Empty--z
Not empty--n

Practical Examples

hljs bash
#!/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
Knowledge Check

Which operator correctly compares if x is greater than 10?

Quick Reference

NumericStringMeaning
-eq==Equal
-ne!=Not equal
-lt<Less than
-gt>Greater than
-le-Less or equal
-ge-Greater or equal
--zIs empty
--nNot empty

Key Takeaways

  • Use -eq, -lt, -gt for numbers in [[ ]]
  • Use <, >, == for strings in [[ ]]
  • Use normal operators in (( )) for math
  • -z checks if empty, -n checks if not empty
  • [[ $file == *.txt ]] for pattern matching
  • [[ $str =~ regex ]] for regex matching

Next: loops - repeat actions with for loops.