Essential Comparison Operators in Shell Scripting
Shell scripts rely on comparison operators to evaluate conditions. These operators are primarily used with the [ ] test construct or the test command. They are categorized based on the data they evaluate: files, strings, and integers.
File Test Operators
These operators check the properties of a file or directory.
| Operator | Description | Example |
|---|---|---|
-e |
True if the file exists. | [ -e /var/log/app.log ] |
-d |
True if the path is a directory. | [ -d /tmp/data ] |
-f |
True if the path is a regular file. | [ -f /bin/bash ] |
-L |
True if the path is a symbolic link. | [ -L /usr/bin/python ] |
-r |
True if the file is readable. | [ -r config.cfg ] |
-w |
True if the file is writable. | [ -w output.txt ] |
-x |
True if the file is executable. | [ -x ./install.sh ] |
-nt |
True if file1 is newer than file2. | [ backup.tar -nt source.tar ] |
-ot |
True if file1 is older than file2. | [ old.log -ot new.log ] |
String Comparison Operators
Always quote variables in string comparisons to prevent word splitting or globbing issues.
| Operator | Description | Example |
|---|---|---|
-z |
True if the string length is zero. | [ -z "$input" ] |
-n |
True if the string length is non-zero. | [ -n "$username" ] |
= or == |
True if strings are equal. | [ "$host" = "localhost" ] |
!= |
True if strings are not equal. | [ "$mode" != "test" ] |
< |
True if string1 sorts before string2 (ASCII). Must be escaped in [ ]: \<. |
[[ "apple" < "banana" ]] |
> |
True if string1 sorts after string2 (ASCII). Must be escaped in [ ]: \>. |
[[ "zebra" > "apple" ]] |
For pattern matching within strings, use the =~ operator inside the [[ ]] construct.
url="https://example.com"
if [[ "$url" =~ "example" ]]; then
echo "Substring found."
fi
Integer Comparison Operators
These operators compare whole numbers. Do not use them for floating-point arithmetic.
| Operator | Description | Example |
|---|---|---|
-eq |
Equal to. | [ "$count" -eq 10 ] |
-ne |
Not equal to. | [ "$retries" -ne 0 ] |
-lt |
Less than. | [ "$value" -lt 100 ] |
-le |
Less than or equal to. | [ "$index" -le "$max" ] |
-gt |
Greater than. | [ "$pid" -gt 0 ] |
-ge |
Greater than or equal to. | [ "$version" -ge 2 ] |
With in double parentheses (( )), you can use standard arithmetic symbols (<, <=, >, >=, ==, !=).
if (( fileSize < 1024 )); then
echo "File is small."
fi
Combining Conditions
Logical operators -a (AND), -o (OR), and ! (NOT) can combine multiple tests within a single [ ] or test command. The && and || operators are also commonly used between separate test comamnds.
primary="yes"
secondary="no"
if [ "$primary" = "yes" -a "$secondary" = "no" ]; then
echo "Condition met."
fi
if [ ! -f "/tmp/lockfile" ]; then
echo "Lock file not present."
fi
test Command
The test command is functionally equivalent to the [ ] construct. The operators listed above work identically with it.
if test -d "$HOME/downloads"; then
echo "Downloads directory exists."
fi
Parameter and Variable Manipulation
Bash provides powerful variable substitution and manipulation features.
| Expression | Description |
|---|---|
${var:-default} |
Use default if var is unset or empty. |
${var:=default} |
Use and assign default to var if it is unset or empty. |
${var:?error_msg} |
Exit with error_msg if var is unset or empty. |
${var:+replacement} |
Use replacement only if var is set and non-empty. |
${#var} |
Length of the string in var. |
${var#pattern} |
Remove shortest leading match of pattern. |
${var##pattern} |
Remove longest leading match of pattern. |
${var%pattern} |
Remove shortest trailing match of pattern. |
${var%%pattern} |
Remove longest trailing match of pattern. |
${var/old/new} |
Replace first match of old with new. |
${var//old/new} |
Replace all matches of old with new. |
Practical Example: Argument Handling
This script demonstrates checking the number of command-line arguments and providing a default value.
#!/bin/bash
# Set default port
connection_port=8080
# Check if at least one argument was provided
if [ $# -ge 1 ]; then
connection_port=$1
fi
echo "Connecting to service on port: $connection_port"
# Command to connect would follow...