Conditionals

Scripts need to make decisions. "If this, then that" - the foundation of programming.

Basic if Statement

hljs bash
#!/bin/bash

if [ -f "config.txt" ]; then
    echo "Config file exists"
fi

Spaces Are Critical

[ -f "file" ] โœ“ (spaces after [ and before ]) [-f "file"] โœ— (will error)

if-else

hljs bash
if [ -f "config.txt" ]; then
    echo "Loading config..."
else
    echo "Config not found, using defaults"
fi

if-elif-else

hljs bash
#!/bin/bash

score=75

if [ "$score" -ge 90 ]; then
    echo "Grade: A"
elif [ "$score" -ge 80 ]; then
    echo "Grade: B"
elif [ "$score" -ge 70 ]; then
    echo "Grade: C"
else
    echo "Grade: F"
fi

Single Bracket vs Double Bracket

Single Bracket [ ] (POSIX)

hljs bash
if [ "$name" = "John" ]; then    # string comparison
if [ "$age" -eq 30 ]; then       # number comparison

Double Bracket [[ ]] (Bash)

hljs bash
if [[ "$name" == "John" ]]; then  # string comparison
if [[ "$age" -eq 30 ]]; then      # number comparison
if [[ "$file" == *.txt ]]; then   # pattern matching!

Prefer [[ ]]

Double brackets are safer (no word splitting issues) and support more features. Use them unless you need POSIX compatibility.

File Tests

TestTrue If
-e fileFile exists
-f fileIs regular file
-d fileIs directory
-r fileIs readable
-w fileIs writable
-x fileIs executable
-s fileFile size > 0
hljs bash
#!/bin/bash

if [[ -d "/var/log" ]]; then
    echo "/var/log is a directory"
fi

if [[ -x "./script.sh" ]]; then
    ./script.sh
else
    echo "Script not executable"
fi

String Tests

TestTrue If
-z "$str"String is empty
-n "$str"String is not empty
"$a" == "$b"Strings are equal
"$a" != "$b"Strings differ
hljs bash
#!/bin/bash

name=""

if [[ -z "$name" ]]; then
    echo "Name is empty"
fi

if [[ "$USER" == "root" ]]; then
    echo "Running as root"
fi

Combining Conditions

AND (&&)

hljs bash
if [[ -f "file.txt" && -r "file.txt" ]]; then
    echo "File exists and is readable"
fi

OR (||)

hljs bash
if [[ "$1" == "start" || "$1" == "run" ]]; then
    echo "Starting..."
fi

NOT (!)

hljs bash
if [[ ! -f "lock.file" ]]; then
    echo "No lock file, safe to proceed"
fi

Short-Circuit Evaluation

hljs bash
# Run command only if file exists
[[ -f "script.sh" ]] && ./script.sh

# Run command only if file doesn't exist
[[ -f "config.txt" ]] || echo "Config missing!"

# Common pattern
[[ -d "$dir" ]] || mkdir -p "$dir"

The test Command

[ ] is actually the test command:

Terminal
$test -f file.txt && echo exists
(same as [ -f file.txt ])
$[ -f file.txt ] && echo exists
exists

Practical Example

hljs bash
#!/bin/bash
# Backup script with checks

backup_dir="/backup"
source_dir="/var/www"

# Check if running as root
if [[ "$EUID" -ne 0 ]]; then
    echo "Please run as root"
    exit 1
fi

# Create backup dir if missing
if [[ ! -d "$backup_dir" ]]; then
    mkdir -p "$backup_dir"
fi

# Check source exists
if [[ -d "$source_dir" ]]; then
    cp -r "$source_dir" "$backup_dir"
    echo "Backup complete"
else
    echo "Source directory not found"
    exit 1
fi
Knowledge Check

What does the test [ -z $var ] check?

Quick Reference

SyntaxPurpose
if [[ ]]; then ... fiBasic if
if ... else ... fiIf-else
if ... elif ... else ... fiMultiple conditions
-f fileFile exists
-d dirDirectory exists
-z "$var"String is empty
$a == $bStrings equal
$a -eq $bNumbers equal
&& / `

Key Takeaways

  • if [[ condition ]]; then ... fi is the basic structure
  • Spaces inside brackets are required
  • Use [[ ]] for bash scripts (safer, more features)
  • -f tests files, -d tests directories
  • -z checks empty strings, -n checks non-empty
  • Combine with && (and), || (or), ! (not)

Next: numeric comparison operators in detail.