LearnAI ToolsCareerPractice BuildsPlayDevelopmentContact
Linux & Command LineIntermediate~1.5 hours

Automated Backups with Rotation and cron

Build a backup script that archives a folder with a timestamp, keeps only the newest copies, proves backups restore correctly, and runs every night with cron.

tarBash ScriptscronFile Rotation

Overview

Backups are only useful if they happen automatically, do not fill the disk, and actually restore. This project builds all three properties into a small, production-style script: timestamped archives, automatic deletion of old ones, a restore test, and a nightly schedule.

What You'll Build
  • backup-rotate.sh: archives any folder into ~/backups/<name>/ with a timestamp.
  • Rotation that keeps only the newest N archives.
  • A restore check that proves the archive matches the original files.
  • A cron entry that runs the backup every night and logs the results.

Prerequisites

  • Shell scripting, functions and exit codes — lesson 12.
  • cron and full paths — lesson 14.
  • A folder to back up (the examples use ~/website).

Step 1: The Backup Script

Save this as ~/bin/backup-rotate.sh and make it executable with chmod +x ~/bin/backup-rotate.sh:

~/bin/backup-rotate.sh
#!/bin/bash
# backup-rotate.sh: archive a folder and keep only the newest N backups
set -euo pipefail
SOURCE="${1:?Usage: $0 <folder> [keep]}"
KEEP="${2:-5}"
DEST="$HOME/backups/$(basename "$SOURCE")"
STAMP="$(date +%Y-%m-%d_%H-%M-%S)"
ARCHIVE="$DEST/$(basename "$SOURCE")_$STAMP.tar.gz"
[ -d "$SOURCE" ] || { echo "Error: '$SOURCE' is not a folder" >&2; exit 2; }
mkdir -p "$DEST"
tar -czf "$ARCHIVE" -C "$(dirname "$SOURCE")" "$(basename "$SOURCE")"
echo "$(date '+%F %T') created $(basename "$ARCHIVE") ($(du -h "$ARCHIVE" | cut -f1))"
# Delete everything except the newest $KEEP archives.
ls -1t "$DEST"/*.tar.gz | tail -n +$((KEEP + 1)) | while read -r old; do
rm -- "$old"
echo "$(date '+%F %T') removed old backup $(basename "$old")"
done
  • ${1:?Usage…} stops with a usage message if no folder is given; ${2:-5} defaults to keeping 5 archives.
  • The timestamp uses only letters, digits, dashes and underscores, so file names are safe and sort in date order.
  • ls -1t lists archives newest first; tail -n +$((KEEP + 1)) selects everything after the first KEEP, and the loop deletes those.
  • Every line of output starts with a date and time, which makes the log easy to read later.

Step 2: First Backup

Back up ~/website, keeping 3 archives:

~/bin/backup-rotate.sh ~/website 3
Output

Click Run to see what this code prints.

Step 3: Test the Rotation

Run it three more times, a second apart. On the fourth archive, the oldest one should be removed:

for i in 1 2 3; do sleep 1; ~/bin/backup-rotate.sh ~/website 3; done
Output

Click Run to see what this code prints.

ls -1 ~/backups/website
Output

Click Run to see what this code prints.

Step 4: Prove the Restore Works

An untested backup is just a hope. Extract the newest archive into a separate folder and compare it with the original using diff -r, which prints nothing when two folders are identical:

mkdir -p ~/restore-test
latest=$(ls -1t ~/backups/website/*.tar.gz | head -n 1)
tar -xzf "$latest" -C ~/restore-test
diff -r ~/website ~/restore-test/website && echo "Restore OK: files match"
Output

Click Run to see what this code prints.

The script also rejects bad input with a non-zero exit code, which cron and monitoring tools can detect:

~/bin/backup-rotate.sh ~/nope
echo "exit code: $?"
Output

Click Run to see what this code prints.

Step 5: Schedule It with cron

Open your crontab with crontab -e and add a line to back up every night at 02:30, keeping a week of archives and appending all output to a log:

crontab -l
Output

Click Run to see what this code prints.

Check That It Ran

The next morning, run tail ~/backups/backup.log. If a cron job fails silently, the log is where you will find out why — usually a missing full path.

Extend This Project

  • Copy each new archive to another machine with rsync or scp over SSH (lesson 13) — a backup on the same disk does not survive a disk failure.
  • Back up several folders by looping over a list in a small wrapper script.
  • Send yourself an email or chat notification when the script exits with an error.
  • Add a weekly cron job that runs the restore test automatically.

Summary

You built a dependable backup system: timestamped archives, automatic rotation, a verified restore and a nightly schedule — the same principles used for real servers.