Skip to content

Instantly share code, notes, and snippets.

@doggoTalent
Last active June 17, 2026 21:57
Show Gist options
  • Select an option

  • Save doggoTalent/5e6bccd752f7a16ce6048970ce1cfb56 to your computer and use it in GitHub Desktop.

Select an option

Save doggoTalent/5e6bccd752f7a16ce6048970ce1cfb56 to your computer and use it in GitHub Desktop.
Simple rotation backup script
#!/bin/bash
#
# backup.sh – Simple rotation backup script
#
# Creates a compressed archive of SOURCE into TARGET with a timestamp,
# and keeps only the most recent MAX_BACKUPS archives.
#
# Requirements: Bash 4+, cron
# -------------------- Configuration --------------------
# Path to the directory or file to be backed up
SOURCE="/path/to/source"
# Path where backup archives will be stored
TARGET="/path/to/backup"
# Prefix for backup archive filenames
PREFIX="backup"
# Maximum number of backup archives to keep (older ones are removed)
MAX_BACKUPS=10
# -------------------- Main script --------------------
# Create TARGET if it doesn't exist (with parent directories)
mkdir -p "$TARGET"
# Timestamp in YYYYMMDD_HHMM format
DATETIME=$(date +"%Y%m%d_%H%M")
# Full path of the new archive
BACKUP_FILE="$TARGET/${PREFIX}_${DATETIME}.tar.gz"
# Create compressed tarball:
# -C changes to SOURCE's parent, so the archive contains only the basename
tar -czf "$BACKUP_FILE" -C "$(dirname "$SOURCE")" "$(basename "$SOURCE")"
# List existing archives, sorted newest-first (ls -1t)
mapfile -t FILES < <(ls -1t "$TARGET"/${PREFIX}_*.tar.gz 2>/dev/null)
# If we have more than MAX_BACKUPS, delete the oldest ones
if [ ${#FILES[@]} -gt $MAX_BACKUPS ]; then
# The array is sorted newest → oldest.
# The oldest are at indices MAX_BACKUPS .. end.
# Delete all files from index MAX_BACKUPS onward.
for ((i=MAX_BACKUPS; i<${#FILES[@]}; i++)); do
rm -f "${FILES[$i]}"
done
fi
# -------------------- End of script --------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment