Overview
A robust backup script with automatic rotation to manage disk space. Supports multiple retention policies: daily, weekly, and monthly backups.
The Script
#!/bin/bash
# Backup with Rotation
# Usage: ./backup-rotate.sh <source> <backup_dir>
set -euo pipefail
# Configuration
KEEP_DAILY=7
KEEP_WEEKLY=4
KEEP_MONTHLY=6
# Timestamp formats
DATE_DAILY=$(date +%Y-%m-%d)
DATE_WEEKLY=$(date +%Y-W%V)
DATE_MONTHLY=$(date +%Y-%m)
TIMESTAMP=$(date +%Y-%m-%d_%H%M%S)
SOURCE="$1"
BACKUP_DIR="$2"
# Create backup directories
DAILY_DIR="$BACKUP_DIR/daily"
WEEKLY_DIR="$BACKUP_DIR/weekly"
MONTHLY_DIR="$BACKUP_DIR/monthly"
mkdir -p "$DAILY_DIR" "$WEEKLY_DIR" "$MONTHLY_DIR"
# Get source name for backup filename
SOURCE_NAME=$(basename "$SOURCE")
echo "Starting backup of $SOURCE"
# Create daily backup
DAILY_BACKUP="$DAILY_DIR/\${SOURCE_NAME}_\${TIMESTAMP}.tar.gz"
tar -czf "$DAILY_BACKUP" -C "$(dirname "$SOURCE")" "$(basename "$SOURCE")"
BACKUP_SIZE=$(du -h "$DAILY_BACKUP" | cut -f1)
echo "Daily backup created: $BACKUP_SIZE"
# Rotation - remove old backups
find "$DAILY_DIR" -name "\${SOURCE_NAME}_*" -mtime +$KEEP_DAILY -delete 2>/dev/null || true
find "$WEEKLY_DIR" -name "\${SOURCE_NAME}_*" -mtime +$((KEEP_WEEKLY * 7)) -delete 2>/dev/null || true
find "$MONTHLY_DIR" -name "\${SOURCE_NAME}_*" -mtime +$((KEEP_MONTHLY * 30)) -delete 2>/dev/null || true
echo "Backup complete!"Usage
# Basic backup
./backup-rotate.sh /var/www /backups/www
# Compressed backup with custom retention
./backup-rotate.sh -c -d 14 -w 8 ~/documents /backups/docs
# With exclude file
./backup-rotate.sh -e exclude.txt /home /backups/homeCron Setup
# Daily backup at 2 AM
0 2 * * * /usr/local/bin/backup-rotate.sh -c /var/www /backups/www >> /var/log/backup.log 2>&1 - backup
- rotation
- tar
- gzip
- rsync
- cron
- retention