Basic Conditional Structures

When to Use Conditional Statements

  • When your script needs to make decisions based on user input
  • When you need to handle different cases or scenarios
  • When you want to check if files or directories exist before using them
  • When you need to validate input before processing it
  • When you need to handle errors or unexpected conditions

Common Conditional Structures

Structure What It Does When to Use It
Basic if statement Executes commands only if a condition is true When you have a single condition to check
if-else statement Executes one set of commands if condition is true, another if false When you need to handle both true and false cases
if-elif-else statement Checks multiple conditions in sequence When you have multiple possible scenarios
Nested if statements Places if statements inside other if statements When conditions depend on other conditions

Practical Examples

# Basic if statement
number=5
if [[ $number -gt 3 ]]; then
    echo "The number is greater than 3"
fi

# if-else statement
number=2
if [[ $number -gt 3 ]]; then
    echo "The number is greater than 3"
else
    echo "The number is not greater than 3"
fi

# if-elif-else statement
number=3
if [[ $number -gt 3 ]]; then
    echo "The number is greater than 3"
elif [[ $number -eq 3 ]]; then
    echo "The number is equal to 3"
else
    echo "The number is less than 3"
fi

# Nested if statement
number=4
if [[ $number -gt 0 ]]; then
    if [[ $number -lt 10 ]]; then
        echo "The number is between 1 and 9"
    else
        echo "The number is 10 or greater"
    fi
else
    echo "The number is zero or negative"
fi

Test Commands: [[ ]] vs [ ]

When to Use Different Test Commands

  • Use [[ ]] when writing scripts specifically for Bash
  • Use [ ] when writing scripts that need to run on multiple Unix-like systems
  • Use [[ ]] when you need pattern matching or advanced string operations
  • Use [ ] for maximum portability across different shells
  • Use [[ ]] when working with variables that might contain spaces or be empty

Comparison of Test Commands

Feature [ ] (Single Brackets) [[ ]] (Double Brackets)
Shell Support POSIX-compliant (works in all shells) Bash, Ksh, Zsh only
String Handling Requires quoting variables More forgiving with variable quoting
Logical Operators Uses -a (AND), -o (OR) Uses && (AND), || (OR)
Pattern Matching Not supported directly Supports =~ for regex
Word Splitting Performs word splitting on variables Prevents word splitting on variables

Practical Examples

# String comparison with [ ]
VAR="hello"
if [ "$VAR" = "hello" ]; then
    echo "Matched with single brackets"
fi

# String comparison with [[ ]]
VAR="hello"
if [[ $VAR == "hello" ]]; then
    echo "Matched with double brackets"
fi

# Logical operators with [ ]
if [ "$num" -gt 5 -a "$num" -lt 10 ]; then
    echo "Number is between 6 and 9 (using single brackets)"
fi

# Logical operators with [[ ]]
if [[ $num -gt 5 && $num -lt 10 ]]; then
    echo "Number is between 6 and 9 (using double brackets)"
fi

# Pattern matching (only works with [[ ]])
filename="document.txt"
if [[ $filename == *.txt ]]; then
    echo "Text file detected"
fi

# Regex matching (only works with [[ ]])
VAR="hello123"
if [[ $VAR =~ ^hello[0-9]+$ ]]; then
    echo "Matches regex pattern"
fi

Comparison Operators

When to Use Different Comparison Types

  • Use string comparisons when working with text
  • Use numeric comparisons when working with numbers
  • Use file test operators when checking file properties
  • Use string pattern matching when searching for specific patterns
  • Use logical operators to combine multiple conditions

Common Comparison Operators

Comparison Type Operator Description
String Comparison == Equal to
!= Not equal to
=~ Matches regular expression (only with [[ ]])
Numeric Comparison -eq Equal to
-ne Not equal to
-gt Greater than
-lt Less than
-ge Greater than or equal to
-le Less than or equal to
String Tests -z String is empty
-n String is not empty
File Tests -f File exists and is a regular file
-d File exists and is a directory
-r File exists and is readable
Logical Operators && Logical AND
|| Logical OR

Practical Examples

# String comparison
name="Alice"
if [[ $name == "Alice" ]]; then
    echo "Hello Alice!"
fi

# Numeric comparison
age=25
if [[ $age -ge 18 ]]; then
    echo "You are an adult"
fi

# String emptiness test
input=""
if [[ -z $input ]]; then
    echo "No input provided"
fi

# File test
if [[ -f "config.txt" ]]; then
    echo "Config file exists, reading settings..."
    cat config.txt
else
    echo "Creating default config file..."
    echo "default_setting=true" > config.txt
fi

# Combining conditions with logical operators
temperature=72
humidity=65
if [[ $temperature -gt 70 && $humidity -lt 80 ]]; then
    echo "Weather is warm and comfortable"
fi

# String pattern matching
filename="document.pdf"
if [[ $filename == *.pdf ]]; then
    echo "PDF document detected"
elif [[ $filename == *.txt ]]; then
    echo "Text file detected"
else
    echo "Unknown file type"
fi

Advanced Conditional Techniques

When to Use Advanced Techniques

  • When you need to handle complex decision trees
  • When you want to create more concise and readable code
  • When checking multiple related conditions
  • When you need to validate input against patterns
  • When your script needs to adapt to different environments

Advanced Conditional Techniques

Technique What It Does When to Use It
Short-circuit evaluation Uses && and || to execute commands conditionally For simple conditional execution without full if statements
Case statements Matches a value against multiple patterns When checking a single variable against many possible values
Command success testing Uses a command's exit status in a condition When your condition depends on a command's success
Parameter expansion with defaults Sets default values for variables that are unset or empty For handling optional parameters gracefully

Practical Examples

# Short-circuit evaluation
[[ -f config.txt ]] && echo "Config file exists"
[[ -f config.txt ]] || echo "Config file missing"

# Command success as a condition
if grep -q "error" log.txt; then
    echo "Errors found in log file"
fi

# Testing command-line arguments
if [[ $# -lt 2 ]]; then
    echo "Error: Not enough arguments"
    echo "Usage: $0 filename count"
    exit 1
fi

# Parameter expansion with default
name=${1:-"Guest"}  # Use "Guest" if $1 is not provided
echo "Hello, $name!"

# Complex condition with multiple checks
file=$1
if [[ -f $file && -r $file && $file == *.txt ]]; then
    echo "Reading text file: $file"
    cat "$file"
else
    echo "File $file is not a readable text file"
fi