Skip to content

Instantly share code, notes, and snippets.

@ferthalangur
Last active January 6, 2017 19:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ferthalangur/8e54880ba406e609dec2 to your computer and use it in GitHub Desktop.
Save ferthalangur/8e54880ba406e609dec2 to your computer and use it in GitHub Desktop.
Prune Apple OS X Time Machine backups
#!/bin/bash
#############################################################################
# Bash script to delete some number of Apple OS X
# Time Machine (TM) backups, always keeping a minimum number. The goal
# is to rely on the _tmutil_ utility instead of physically accessing
# the files directly ... in hopes that this is less likely to corrupt
# the Time Machine database.
#
# Defaults are set to delete up to 5 backups, and keep a minimum of 5
#
# I have tested this with TM on OS X 10.8.5 (Mountain Lion) with a
# locally-mounted TM disk. I haven't tried it with a TM disk in a Time
# Capsule setup.
#
# Assumptions:
# - You run this as root or with sudo
# - You will run this when the Time Machine disk is attached!
# - You run it on the command line (Terminal) and you'll stick around
# in case your sudo ticket times out. Deleting a TM backup can
# take a while.
#
# Todo:
# - Concurrency protection -- create/check for lockfile
# - Test with Time Capsule / Networked TM
#############################################################################
#
# Author: Rob Jenson - https://github.com/ferthalangur
#
# Copyright 2015 Center for Hellenic Studies, Trustees for Harvard University
# http://chs.harvard.edu
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#############################################################################
#
# Configurable Parameters:
# =======================
#
# Minimum number to keep under all circumstances
PTB_MINKEEP=${PTB_MINKEEP-5}
# Number to delete, constrained by $PTB_MINKEEP
PTB_COUNT=${PTB_COUNT-5}
# Change this to "false" to be more verbose:
PTB_SILENT=${PTB_SILENT-"true"}
# No User-Servicable Parts Below Here:
# ====================================
PROGNAME=`basename $0`
# Functions:
function initialize {
TEMPLIST=`mktemp -t "ptb_temp.XXXXXX"`
}
# Cleanup takes a return value
function cleanup {
returnvalue=$1
shift
rm -f ${TEMPLIST}
exit $returnvalue
}
# `check_fatal` will attempt to run a command and exit if it fails
function check_fatal {
"$@"
status=$?
if [ $status -ne 0 ]; then
echo "ERROR: Encountered error (${status}) while running the following:" >&2
echo " $@" >&2
echo " (at line ${BASH_LINENO[0]} of file $0.)" >&2
echo " Aborting." >&2
exit $status
fi
}
initialize
check_fatal tmutil listbackups | sort -o ${TEMPLIST}
backup_count=`wc -l ${TEMPLIST} | awk '{print($1)}'`
if [ ${backup_count} -lt ${PTB_MINKEEP} ]
then
${PTB_SILENT} || (
echo "Only ${backup_count} backups exist. This script requires";
echo "a minimum of ${PTB_MINKEEP} kept. Call this script prefixed";
echo "by PTB_MINKEEP=[number] to change that parameter.";
)
cleanup 0
fi
linectr=0
while [ ${linectr} -lt ${PTB_COUNT} -a ${backup_count} -gt ${PTB_MINKEEP} ]
do
read backupname
${PTB_SILENT} || echo "Deleting ${backupname} ..."
check_fatal tmutil delete "${backupname}"
((++linectr))
((--backup_count))
done < ${TEMPLIST}
cleanup 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment