Backup Scripts
Backup scripts are one of the most practical applications of bash scripting. Learn to create reliable, automated backup solutions.
Simple File Backup
Basic backup with timestamp:
#!/bin/bash
SOURCE="/home/user/documents"
DEST="/backup"
DATE=$(date +%Y%m%d_%H%M%S)
cp -r "$SOURCE" "$DEST/documents_$DATE"
echo "Backup completed: documents_$DATE"
Compressed Backup
Create compressed archives:
#!/bin/bash
SOURCE="$1"
BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d)
ARCHIVE="$BACKUP_DIR/$(basename "$SOURCE")_$DATE.tar.gz"
# Create backup directory
mkdir -p "$BACKUP_DIR"
# Create compressed archive
tar -czf "$ARCHIVE" -C "$(dirname "$SOURCE")" "$(basename "$SOURCE")"
echo "Created: $ARCHIVE"
ls -lh "$ARCHIVE"
Exercise: Create Backup Function
Write a backup function:
Incremental Backups
Only backup changed files:
#!/bin/bash
SOURCE="/home/user/documents"
DEST="/backup/incremental"
LAST_BACKUP="$DEST/.last_backup"
mkdir -p "$DEST"
if [ -f "$LAST_BACKUP" ]; then
# Backup only files newer than last backup
find "$SOURCE" -newer "$LAST_BACKUP" -type f | while read -r file; do
rel_path="${file#$SOURCE/}"
mkdir -p "$DEST/$(dirname "$rel_path")"
cp "$file" "$DEST/$rel_path"
echo "Backed up: $rel_path"
done
else
# First backup - copy everything
cp -r "$SOURCE"/* "$DEST/"
fi
# Update timestamp
touch "$LAST_BACKUP"
Rotation Strategy
Keep limited number of backups:
#!/bin/bash
BACKUP_DIR="/backup"
MAX_BACKUPS=7
# Create new backup
DATE=$(date +%Y%m%d_%H%M%S)
create_backup "$DATE"
# Remove old backups
cd "$BACKUP_DIR"
ls -t backup_*.tar.gz | tail -n +$((MAX_BACKUPS + 1)) | while read -r old; do
echo "Removing old backup: $old"
rm "$old"
done
Full Backup Script
Complete backup script with error handling:
#!/bin/bash
set -euo pipefail
# Configuration
SOURCE="${SOURCE:-/home/user/documents}"
DEST="${DEST:-/backup}"
MAX_BACKUPS="${MAX_BACKUPS:-7}"
LOG_FILE="/var/log/backup.log"
# Functions
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"
}
die() {
log "ERROR: $1"
exit 1
}
cleanup_old_backups() {
local count
count=$(ls -1 "$DEST"/backup_*.tar.gz 2>/dev/null | wc -l)
if [ "$count" -gt "$MAX_BACKUPS" ]; then
ls -t "$DEST"/backup_*.tar.gz | tail -n +$((MAX_BACKUPS + 1)) | \
while read -r old; do
log "Removing: $old"
rm "$old"
done
fi
}
# Main
log "Starting backup of $SOURCE"
# Validate
[ -d "$SOURCE" ] || die "Source not found: $SOURCE"
mkdir -p "$DEST" || die "Cannot create destination: $DEST"
# Create backup
DATE=$(date +%Y%m%d_%H%M%S)
ARCHIVE="$DEST/backup_$DATE.tar.gz"
if tar -czf "$ARCHIVE" -C "$(dirname "$SOURCE")" "$(basename "$SOURCE")"; then
log "Created: $ARCHIVE ($(du -h "$ARCHIVE" | cut -f1))"
cleanup_old_backups
log "Backup completed successfully"
else
die "Backup failed"
fi
Database Backup
Backup databases:
#!/bin/bash
DB_NAME="myapp"
BACKUP_DIR="/backup/db"
DATE=$(date +%Y%m%d)
mkdir -p "$BACKUP_DIR"
# PostgreSQL
pg_dump "$DB_NAME" | gzip > "$BACKUP_DIR/${DB_NAME}_$DATE.sql.gz"
# MySQL
mysqldump -u root -p"$DB_PASS" "$DB_NAME" | gzip > "$BACKUP_DIR/${DB_NAME}_$DATE.sql.gz"
# Verify
if [ -f "$BACKUP_DIR/${DB_NAME}_$DATE.sql.gz" ]; then
echo "Database backup successful"
else
echo "Database backup failed!" >&2
exit 1
fi
Remote Backup
Backup to remote server:
#!/bin/bash
SOURCE="/home/user/documents"
REMOTE="backup@server.com:/backups/"
DATE=$(date +%Y%m%d)
# Using rsync (efficient, incremental)
rsync -avz --delete "$SOURCE" "$REMOTE/current/"
# Create dated snapshot
ssh backup@server.com "cp -al /backups/current /backups/backup_$DATE"
echo "Remote backup completed"
Exercise: Verify Backup
Check backup file exists:
Backup Best Practices
- Test restores - Backups are useless if they can't be restored
- Monitor backups - Log and alert on failures
- Encrypt sensitive data - Use gpg for encryption
- Off-site copies - Don't keep all backups in one place
- Verify integrity - Check checksums
- Document procedure - Write restore instructions
# Encrypt backup
tar -czf - "$SOURCE" | gpg -c > backup.tar.gz.gpg
# Verify with checksum
sha256sum backup.tar.gz > backup.tar.gz.sha256
# Later, verify integrity
sha256sum -c backup.tar.gz.sha256
Key Takeaways
- Use timestamps in backup filenames
- Compress backups with
tar -czf - Implement rotation to manage disk space
- Add error handling and logging
- Test restore procedures regularly
- Consider incremental backups for large data
- Use rsync for remote/network backups
- Encrypt sensitive backups

