Skip to content

Instantly share code, notes, and snippets.

@pew
Forked from alanorth/clean-snap-sync-external.sh
Last active May 9, 2025 18:14
Show Gist options
  • Select an option

  • Save pew/6b742615272736e87b731883d1c603c6 to your computer and use it in GitHub Desktop.

Select an option

Save pew/6b742615272736e87b731883d1c603c6 to your computer and use it in GitHub Desktop.
Clean snapshots created by snap-sync
#!/usr/bin/env bash
#
# clean-snap-sync-external.sh v1.0.1 (2021-07-09)
#
# Changes
# -------
# 2021-07-09:
# - adjust logic to keep latest x, instead of delete oldest x
# - make output cleaner (hide btrfs subvolume delete output)
#
# Inspired by FraYoshi's original
# See: https://github.com/wesbarnett/snap-sync/issues/16
# Change these for your environment
readonly snapshot_root=/backup
readonly snapper_config=root # snapper config name
readonly keep_latest=20
# Don't change these
readonly ansi_default="\e[39m"
readonly ansi_green="\e[32m"
readonly ansi_yellow="\e[33m"
echo -e "${ansi_green}[DEBUG] Keeping the latest ${keep_latest} snapshots on ${snapshot_root} for config ${snapper_config}.${ansi_default}"
echo -e " ${ansi_green}[DEBUG] Checking ${snapshot_root}/${snapper_config}${ansi_default}"
# Make sure the total number of snapshots is more than $keep_latest
if [ "$(find "${snapshot_root}/${snapper_config}" -mindepth 1 -maxdepth 1 -type d | wc -l)" -gt "${keep_latest}" ]; then
find "${snapshot_root}/${snapper_config}" -mindepth 1 -maxdepth 1 -type d -printf "%f\n" | sort -nr | tail -n +$((keep_latest + 1)) | while read -r snapnum; do
echo -e " ${ansi_green}[DEBUG] Found ${snapshot_root}/${snapper_config}/${snapnum}${ansi_default}"
if ! snapper -c "${snapper_config}" list --columns number,description | grep -E "^${snapnum}" | grep 'latest incremental backup' >/dev/null; then
echo -e " ${ansi_yellow}[INFO] Deleting ${snapshot_root}/${snapper_config}/${snapnum}${ansi_default}"
btrfs subvolume delete "${snapshot_root}/${snapper_config}/${snapnum}/snapshot" >/dev/null
rm -r "${snapshot_root:?}/${snapper_config}/${snapnum}"
else
echo -e " ${ansi_green}[DEBUG] Not deleting ${snapshot_root}/${snapper_config}/${snapnum} because it is the latest incremental backup.${ansi_default}"
fi
done
else
echo -e " ${ansi_green}[DEBUG] Number of snapshots in ${snapshot_root}/${snapper_config} should be more than ${keep_latest}.${ansi_default}"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment