Skip to content
GreenSnippets

Timestamped tar.gz backup that keeps the newest N

Archive a directory with a sortable timestamp and delete older backups beyond a retention count.

Bash
#!/usr/bin/env bash
set -euo pipefail

SRC="${1:?usage: backup.sh <source-dir> <backup-dir> [keep]}"
DEST="${2:?usage: backup.sh <source-dir> <backup-dir> [keep]}"
KEEP="${3:-7}"

mkdir -p "$DEST"
name="$(basename "$SRC")-$(date +%Y%m%d-%H%M%S).tar.gz"
tar -czf "$DEST/$name" -C "$(dirname "$SRC")" "$(basename "$SRC")"
echo "Created $DEST/$name"

# Newest first; skip the first $KEEP, delete the rest.
ls -1t "$DEST"/"$(basename "$SRC")"-*.tar.gz | tail -n +"$((KEEP + 1))" | while read -r old; do
  rm -- "$old"
  echo "Removed $old"
done

How it works

ISO-style timestamps (20260115-093000) sort alphabetically in date order, so ls shows the newest last. After creating the archive, the script lists existing backups newest first and removes everything beyond KEEP.

Test with echo in front of rm first. Backups on the same disk do not protect against disk failure, so copy them off the machine too. This script has been reviewed but not run through an automated test; it assumes GNU tar and file names without newlines.

This snippet has been reviewed but was not executed by an automated test. Test it in your own environment before relying on it.