SyntaxStudy
Sign Up
Linux / Bash Bash Control Flow: if, for, and while
Linux / Bash Beginner 1 min read

Bash Control Flow: if, for, and while

Control flow statements make scripts dynamic. The `if` statement tests a condition and branches execution. In Bash, conditions use `[[ ]]` (preferred) or `[ ]` (POSIX-compatible) for file tests, string comparisons, and numeric comparisons. The `[[ ]]` form supports logical operators `&&` and `||` and pattern matching without quoting issues. The `for` loop iterates over a list of items. The list can be a brace expansion (`{1..10}`), a glob pattern (`*.txt`), or the output of a command via `$(...)`. The C-style for loop `for ((i=0; i<10; i++))` is useful for numeric iteration. The `while` loop executes a body as long as its condition is true, and `until` runs while the condition is false. The `case` statement matches a value against multiple patterns and is cleaner than a chain of `if/elif` statements for multi-way branching. Functions in Bash are declared with `function name()` or simply `name()`. They accept positional parameters just like scripts and can return an exit status with `return`. Local variables inside functions use the `local` keyword to prevent polluting the global scope.
Example
#!/bin/bash

# ---- if / elif / else ----
FILE="/etc/hosts"

if [[ -f "$FILE" ]]; then
    echo "$FILE exists and is a regular file"
elif [[ -d "$FILE" ]]; then
    echo "$FILE is a directory"
else
    echo "$FILE does not exist"
fi

# String comparison
USER_INPUT="yes"
if [[ "$USER_INPUT" == "yes" ]]; then
    echo "User agreed"
fi

# Numeric comparison (-eq -ne -lt -le -gt -ge)
COUNT=5
if (( COUNT > 3 )); then
    echo "Count is greater than 3"
fi

# ---- for loop ----
# Over a list
for fruit in apple banana cherry; do
    echo "Fruit: $fruit"
done

# Over a range
for i in {1..5}; do
    echo "Iteration $i"
done

# Over files
for f in /etc/*.conf; do
    echo "Config file: $f"
done

# C-style
for (( i=0; i<3; i++ )); do
    echo "Index $i"
done

# ---- while loop ----
counter=1
while (( counter <= 3 )); do
    echo "Counter: $counter"
    (( counter++ ))
done

# Read file line by line
while IFS= read -r line; do
    echo "Line: $line"
done < /etc/hosts

# ---- case statement ----
DAY=$(date +%A)
case "$DAY" in
    Monday|Tuesday|Wednesday|Thursday|Friday)
        echo "Weekday" ;;
    Saturday|Sunday)
        echo "Weekend" ;;
    *)
        echo "Unknown" ;;
esac