Conditionals — if, elif, and else
Make decisions in your Bash scripts with if/elif/else. Understand the structure, common patterns, and how exit codes drive branching.
Decision-making is the backbone of automation. Without if, your script does the same thing regardless of conditions — no checking if a file exists, no different handling for success vs failure, no adapting to input. Once you understand how Bash if works under the hood, it makes complete sense.
How if Works — It's All Exit Codes
Bash's if statement doesn't check a boolean — it runs a command and checks whether it exits with code 0 (success = true) or non-zero (failure = false). Every command, including [, [[, and test, is evaluated this way.
# Basic structure
if command; then
# runs if command exits 0
elif other_command; then
# runs if other_command exits 0 (and first failed)
else
# runs if all above failed
fi # ← closes the if block (literally "if" backwards)
# One-liner (semicolons allowed)
if [ -f file.txt ]; then echo "exists"; fifi closes if
Bash block closers are literally the keyword reversed: if...fi, case...esac. Don't forget fi! Forgetting it causes a confusing 'unexpected end of file' error.
Common if Patterns
# Check command success
if ping -c 1 google.com &>/dev/null; then
echo "Network is up"
else
echo "No network"
fi
# Check a string value
color="blue"
if [[ "$color" == "red" ]]; then
echo "It's red"
elif [[ "$color" == "blue" ]]; then
echo "It's blue"
else
echo "Unknown color"
fi
# Check a number
age=25
if [[ "$age" -ge 18 ]]; then
echo "Adult"
fiLogical Operators — and, or, not
# AND — both conditions must be true
if [[ -f file.txt && -r file.txt ]]; then
echo "file exists and is readable"
fi
# OR — at least one must be true
if [[ "$input" == "yes" || "$input" == "y" ]]; then
echo "User said yes"
fi
# NOT — negate condition
if ! command -v docker &>/dev/null; then
echo "Docker is not installed"
fi
# Chaining with && and || (without if)
mkdir /tmp/mydir && echo "Created OK" || echo "Failed to create"Nested if Statements
#!/usr/bin/env bash
file="${1:-}"
if [[ -z "$file" ]]; then
echo "No file provided" >&2
exit 1
fi
if [[ -f "$file" ]]; then
if [[ -r "$file" ]]; then
echo "Reading $file..."
cat "$file"
else
echo "File exists but is not readable" >&2
exit 1
fi
elif [[ -d "$file" ]]; then
echo "$file is a directory, not a file"
else
echo "$file does not exist"
fiInline Conditionals
# Short-circuit evaluation
[[ -f backup.tar.gz ]] && echo "Backup exists"
[[ -d /tmp/work ]] || mkdir -p /tmp/work # create if not exists
# These are equivalent to if/else but more concise
# Use sparingly — readability suffers in complex casesWhat does Bash actually check when evaluating `if some_command; then`?
Write a script check-user.sh that accepts a username as argument and:
- If no argument given → print "Usage..." and exit 1
- If the user exists on the system (use
id username) → print "User alice exists" - If the user doesn't exist → print "User alice not found"