Conditional Statements
Conditional statements allow your scripts to make decisions and execute different code paths based on conditions. They are essential for creating intelligent, responsive scripts that can handle various scenarios.
The if Statement
The if statement is the most basic conditional construct in Bash.
Basic Syntax
if [ condition ]; then
# commands to execute if condition is true
fiSimple Example
#!/bin/bash
age=20
if [ $age -ge 18 ]; then
echo "You are an adult"
fiif-else Statement
Add an alternative path when the condition is false:
#!/bin/bash
age=16
if [ $age -ge 18 ]; then
echo "You are an adult"
else
echo "You are a minor"
fiif-elif-else Statement
Handle multiple conditions:
#!/bin/bash
score=85
if [ $score -ge 90 ]; then
echo "Grade: A"
elif [ $score -ge 80 ]; then
echo "Grade: B"
elif [ $score -ge 70 ]; then
echo "Grade: C"
elif [ $score -ge 60 ]; then
echo "Grade: D"
else
echo "Grade: F"
fiTest Conditions
Numeric Comparisons
#!/bin/bash
num1=10
num2=20
# Equal
if [ $num1 -eq $num2 ]; then
echo "Numbers are equal"
fi
# Not equal
if [ $num1 -ne $num2 ]; then
echo "Numbers are not equal"
fi
# Greater than
if [ $num1 -gt $num2 ]; then
echo "$num1 is greater than $num2"
fi
# Less than
if [ $num1 -lt $num2 ]; then
echo "$num1 is less than $num2"
fi
# Greater than or equal
if [ $num1 -ge $num2 ]; then
echo "$num1 is greater than or equal to $num2"
fi
# Less than or equal
if [ $num1 -le $num2 ]; then
echo "$num1 is less than or equal to $num2"
fiString Comparisons
#!/bin/bash
name1="Alice"
name2="Bob"
empty_string=""
# String equality
if [ "$name1" = "$name2" ]; then
echo "Names are the same"
else
echo "Names are different"
fi
# String inequality
if [ "$name1" != "$name2" ]; then
echo "Names are different"
fi
# String length (non-zero)
if [ -n "$name1" ]; then
echo "Name1 is not empty"
fi
# String length (zero)
if [ -z "$empty_string" ]; then
echo "String is empty"
fi
# Lexicographic comparison
if [[ "$name1" < "$name2" ]]; then
echo "$name1 comes before $name2 alphabetically"
fiFile Tests
#!/bin/bash
filename="test.txt"
directory="mydir"
# File exists
if [ -e "$filename" ]; then
echo "File exists"
fi
# Regular file
if [ -f "$filename" ]; then
echo "It's a regular file"
fi
# Directory
if [ -d "$directory" ]; then
echo "It's a directory"
fi
# Readable
if [ -r "$filename" ]; then
echo "File is readable"
fi
# Writable
if [ -w "$filename" ]; then
echo "File is writable"
fi
# Executable
if [ -x "$filename" ]; then
echo "File is executable"
fi
# File size greater than zero
if [ -s "$filename" ]; then
echo "File is not empty"
fi
# Symbolic link
if [ -L "$filename" ]; then
echo "It's a symbolic link"
fiAdvanced Test Constructs
Double Brackets [[ ]]
The [[ ]] construct provides more features than single brackets:
#!/bin/bash
name="Alice"
number="123"
# Pattern matching
if [[ $name == A* ]]; then
echo "Name starts with A"
fi
# Regular expressions
if [[ $number =~ ^[0-9]+$ ]]; then
echo "It's a number"
fi
# Multiple conditions with && and ||
if [[ $name == "Alice" && $number -gt 100 ]]; then
echo "Name is Alice and number is greater than 100"
fi
if [[ $name == "Alice" || $name == "Bob" ]]; then
echo "Name is either Alice or Bob"
fiArithmetic Evaluation (( ))
For numeric comparisons, you can use arithmetic evaluation:
#!/bin/bash
x=10
y=20
if (( x < y )); then
echo "$x is less than $y"
fi
if (( x + y == 30 )); then
echo "Sum is 30"
fi
if (( x % 2 == 0 )); then
echo "$x is even"
fiLogical Operators
AND Operator (&&)
#!/bin/bash
age=25
has_license=true
if [ $age -ge 18 ] && [ "$has_license" = "true" ]; then
echo "Can drive"
fi
# Alternative syntax
if [[ $age -ge 18 && $has_license == "true" ]]; then
echo "Can drive"
fiOR Operator (||)
#!/bin/bash
day="Saturday"
if [ "$day" = "Saturday" ] || [ "$day" = "Sunday" ]; then
echo "It's weekend!"
fi
# Alternative syntax
if [[ $day == "Saturday" || $day == "Sunday" ]]; then
echo "It's weekend!"
fiNOT Operator (!)
#!/bin/bash
filename="test.txt"
# Negate condition
if [ ! -f "$filename" ]; then
echo "File does not exist"
fi
# Alternative
if ! [ -f "$filename" ]; then
echo "File does not exist"
fiPractical Examples
File Backup Script
#!/bin/bash
source_file="$1"
backup_dir="/backup"
# Check if source file is provided
if [ $# -eq 0 ]; then
echo "Usage: $0 <source_file>"
exit 1
fi
# Check if source file exists
if [ ! -f "$source_file" ]; then
echo "Error: Source file '$source_file' does not exist"
exit 1
fi
# Check if backup directory exists
if [ ! -d "$backup_dir" ]; then
echo "Creating backup directory..."
mkdir -p "$backup_dir"
fi
# Create backup
backup_name="$(basename "$source_file").backup.$(date +%Y%m%d_%H%M%S)"
if cp "$source_file" "$backup_dir/$backup_name"; then
echo "Backup created: $backup_dir/$backup_name"
else
echo "Error: Failed to create backup"
exit 1
fiSystem Health Check
#!/bin/bash
# System health check script
echo "=== System Health Check ==="
# Check disk usage
disk_usage=$(df / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ $disk_usage -gt 90 ]; then
echo "WARNING: Disk usage is ${disk_usage}%"
elif [ $disk_usage -gt 80 ]; then
echo "CAUTION: Disk usage is ${disk_usage}%"
else
echo "OK: Disk usage is ${disk_usage}%"
fi
# Check memory usage
memory_usage=$(free | awk 'NR==2{printf "%.0f", $3*100/$2}')
if [ $memory_usage -gt 90 ]; then
echo "WARNING: Memory usage is ${memory_usage}%"
else
echo "OK: Memory usage is ${memory_usage}%"
fi
# Check if critical services are running
services=("ssh" "nginx" "mysql")
for service in "${services[@]}"; do
if systemctl is-active --quiet "$service"; then
echo "OK: $service is running"
else
echo "ERROR: $service is not running"
fi
doneUser Input Validation
#!/bin/bash
# User registration script with validation
echo "User Registration"
echo "=================="
# Get username
while true; do
read -p "Enter username (3-20 characters, alphanumeric only): " username
if [[ -z "$username" ]]; then
echo "Username cannot be empty"
elif [[ ${#username} -lt 3 ]]; then
echo "Username must be at least 3 characters"
elif [[ ${#username} -gt 20 ]]; then
echo "Username must be no more than 20 characters"
elif [[ ! $username =~ ^[a-zA-Z0-9]+$ ]]; then
echo "Username can only contain letters and numbers"
else
break
fi
done
# Get email
while true; do
read -p "Enter email address: " email
if [[ -z "$email" ]]; then
echo "Email cannot be empty"
elif [[ ! $email =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
echo "Please enter a valid email address"
else
break
fi
done
# Get age
while true; do
read -p "Enter age (18-120): " age
if [[ ! $age =~ ^[0-9]+$ ]]; then
echo "Age must be a number"
elif [ $age -lt 18 ]; then
echo "You must be at least 18 years old"
elif [ $age -gt 120 ]; then
echo "Please enter a realistic age"
else
break
fi
done
echo
echo "Registration successful!"
echo "Username: $username"
echo "Email: $email"
echo "Age: $age"Nested Conditionals
You can nest if statements for complex logic:
#!/bin/bash
weather="sunny"
temperature=75
if [ "$weather" = "sunny" ]; then
if [ $temperature -gt 70 ]; then
echo "Perfect day for outdoor activities!"
else
echo "Sunny but a bit cold"
fi
elif [ "$weather" = "rainy" ]; then
if [ $temperature -gt 60 ]; then
echo "Warm rain, good for plants"
else
echo "Cold and rainy, stay inside"
fi
else
echo "Weather is $weather"
fiShort-Circuit Evaluation
Use && and || for concise conditional execution:
#!/bin/bash
filename="test.txt"
# Execute command only if condition is true
[ -f "$filename" ] && echo "File exists"
# Execute command only if condition is false
[ ! -f "$filename" ] || echo "File exists"
# Chain multiple conditions
[ -f "$filename" ] && [ -r "$filename" ] && echo "File exists and is readable"
# Alternative to if-else
[ $# -eq 0 ] && echo "No arguments provided" || echo "Arguments provided"Common Pitfalls and Best Practices
1. Always Quote Variables
# Wrong - can break with spaces
if [ $name = "John Doe" ]; then
echo "Hello John"
fi
# Correct
if [ "$name" = "John Doe" ]; then
echo "Hello John"
fi2. Use [[ ]] for String Operations
# Better for pattern matching and regex
if [[ $filename == *.txt ]]; then
echo "Text file"
fi
if [[ $email =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
echo "Valid email"
fi3. Handle Empty Variables
# Safe way to handle potentially empty variables
if [ -n "${name:-}" ]; then
echo "Name is set: $name"
else
echo "Name is not set"
fi4. Use Meaningful Conditions
# Good - readable and clear
if [ $user_age -ge $minimum_age ]; then
grant_access
fi
# Bad - unclear magic numbers
if [ $age -ge 21 ]; then
do_something
fi5. Exit Codes for Error Handling
#!/bin/bash
if ! command_that_might_fail; then
echo "Command failed"
exit 1
fi
# Or check exit code explicitly
command_that_might_fail
if [ $? -ne 0 ]; then
echo "Command failed with exit code $?"
exit 1
fiConditional statements are the foundation of decision-making in shell scripts. Master these concepts to create scripts that can intelligently respond to different situations and handle various scenarios gracefully.