Real-World Bash Projects

Each project uses variables, functions, loops, conditionals, file handling, and error handling together. These are the kinds of scripts used by developers and system administrators every day.

Project 1 – Automated Directory Backup with Rotation

This script backs up a directory, compresses it with a timestamp, and deletes backups older than 7 days to save disk space.

#!/bin/bash
set -euo pipefail

# ── Configuration ──────────────────────────────────────
SOURCE="/home/john/projects"
DEST="/home/john/backups"
RETAIN_DAYS=7
LOG="$DEST/backup.log"
DATE=$(date +%Y-%m-%d_%H%M%S)

# ── Functions ───────────────────────────────────────────
log() {
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG"
}

create_backup() {
  mkdir -p "$DEST"
  tar -czf "$DEST/backup_$DATE.tar.gz" "$SOURCE"
  log "Backup created: backup_$DATE.tar.gz"
}

delete_old_backups() {
  find "$DEST" -name "backup_*.tar.gz" -mtime +$RETAIN_DAYS -delete
  log "Old backups older than $RETAIN_DAYS days removed"
}

# ── Main ────────────────────────────────────────────────
log "==== Backup Started ===="
create_backup
delete_old_backups
log "==== Backup Finished ===="

Sample log output:

[2026-04-18 02:00:01] ==== Backup Started ====
[2026-04-18 02:00:03] Backup created: backup_2026-04-18_020001.tar.gz
[2026-04-18 02:00:03] Old backups older than 7 days removed
[2026-04-18 02:00:03] ==== Backup Finished ====

Project 2 – System Health Monitor

This script checks CPU load, disk usage, and memory usage. It prints a color-coded report and sends an alert if any threshold exceeds a safe limit.

#!/bin/bash
set -euo pipefail

DISK_LIMIT=80
MEM_LIMIT=85

# ── Get metrics ─────────────────────────────────────────
disk_usage=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
mem_total=$(free | grep Mem | awk '{print $2}')
mem_used=$(free | grep Mem | awk '{print $3}')
mem_percent=$(( mem_used * 100 / mem_total ))
load=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | sed 's/,//')

# ── Display report ──────────────────────────────────────
echo "======================================"
echo "  SYSTEM HEALTH REPORT — $(date +%Y-%m-%d)"
echo "======================================"
printf "  CPU Load    : %s\n" "$load"
printf "  Disk Usage  : %s%%\n" "$disk_usage"
printf "  Memory Used : %s%%\n" "$mem_percent"
echo "======================================"

# ── Alerts ──────────────────────────────────────────────
alert=0
if [ "$disk_usage" -gt "$DISK_LIMIT" ]; then
  echo "  !! ALERT: Disk usage is at ${disk_usage}%"
  alert=1
fi
if [ "$mem_percent" -gt "$MEM_LIMIT" ]; then
  echo "  !! ALERT: Memory usage is at ${mem_percent}%"
  alert=1
fi

if [ "$alert" -eq 0 ]; then
  echo "  All systems normal."
fi

Sample output:

======================================
  SYSTEM HEALTH REPORT — 2026-04-18
======================================
  CPU Load    : 0.42
  Disk Usage  : 61%
  Memory Used : 72%
======================================
  All systems normal.

Project 3 – CSV Report Parser

This script reads a CSV file of student records, calculates grades, and generates a formatted report.

Input file: students.csv

Name,Score
Alice,92
Bob,67
Carol,78
David,45
Eva,85
#!/bin/bash
set -euo pipefail

CSV_FILE="students.csv"

echo "======================================"
echo "          STUDENT GRADE REPORT        "
echo "======================================"
printf "%-12s %-8s %-8s\n" "Name" "Score" "Grade"
echo "--------------------------------------"

# Skip header line, process data rows
tail -n +2 "$CSV_FILE" | while IFS=',' read -r name score
do
  if [ "$score" -ge 90 ]; then
    grade="A+"
  elif [ "$score" -ge 80 ]; then
    grade="A"
  elif [ "$score" -ge 70 ]; then
    grade="B"
  elif [ "$score" -ge 60 ]; then
    grade="C"
  else
    grade="F"
  fi
  printf "%-12s %-8s %-8s\n" "$name" "$score" "$grade"
done

echo "======================================"

Output:

======================================
          STUDENT GRADE REPORT        
======================================
Name         Score    Grade   
--------------------------------------
Alice        92       A+      
Bob          67       C       
Carol        78       B       
David        45       F       
Eva          85       A       
======================================

Project 4 – Interactive Menu-Driven Script

This script creates a small interactive menu that allows a user to perform file management tasks from a numbered menu. This is a pattern used in many admin tools and setup scripts.

#!/bin/bash
set -euo pipefail

# ── Functions ───────────────────────────────────────────
show_files() {
  echo ""
  echo "Files in current directory:"
  ls -lh
  echo ""
}

create_file() {
  read -p "Enter file name: " fname
  touch "$fname"
  echo "File '$fname' created."
}

delete_file() {
  read -p "Enter file name to delete: " fname
  if [ -f "$fname" ]; then
    rm "$fname"
    echo "File '$fname' deleted."
  else
    echo "File not found."
  fi
}

show_disk() {
  echo ""
  df -h /
  echo ""
}

# ── Menu Loop ───────────────────────────────────────────
while true; do
  echo "=============================="
  echo "       FILE MANAGER MENU      "
  echo "=============================="
  echo "  1. List files"
  echo "  2. Create file"
  echo "  3. Delete file"
  echo "  4. Check disk space"
  echo "  5. Exit"
  echo "=============================="
  read -p "Choose option [1-5]: " choice

  case $choice in
    1) show_files ;;
    2) create_file ;;
    3) delete_file ;;
    4) show_disk ;;
    5) echo "Goodbye!"; exit 0 ;;
    *) echo "Invalid option. Please choose 1–5." ;;
  esac
done

Skills Used Across All Projects

ProjectKey Concepts Applied
Backup ScriptFunctions, variables, file handling, date command, find, cron-ready
Health MonitorVariables, arithmetic, conditionals, awk, df, free
CSV ParserFile reading, loops, IFS, conditional grading, printf formatting
Menu ScriptFunctions, infinite loop, case statement, read, error handling

Tips for Writing Good Bash Scripts

  • Always start with #!/bin/bash and set -euo pipefail.
  • Use functions to organize logic into named blocks.
  • Add comments to explain why — not just what — the code does.
  • Log important events with timestamps for troubleshooting.
  • Use full paths in scripts meant for cron or automation.
  • Test scripts on sample data before running on production files.
  • Use bash -n script.sh to check syntax before the first run.

Leave a Comment