Last active
March 30, 2018 00:59
-
-
Save higarin/99513d2b03aee0922e9be3004bb18790 to your computer and use it in GitHub Desktop.
rsync TimeMachine
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# Backup mimicking Time Machine from Mac OS X using rsync | |
# --- Variables --- # | |
OS=$(uname -s) | |
HOST=$(hostname) | |
DATE_FORMAT=$(date "+%Y-%m-%d-%H%M%S") | |
CURRENT_YEAR=$(date +%Y) | |
CURRENT_MONTH=$(date +%m) | |
#RSYNC_OPTIONS="--recursive --links --times -D -O --partial --progress --human-readable" | |
RSYNC_OPTIONS="-auE --partial --progress --human-readable" | |
# Use absolute paths. Relative paths tend to break the hard linking advantage of rsync. | |
# Paths can include spaces as long as variable contents are double quoted | |
# SOURCE="[absolute path to source directory]" | |
# DESTINATION="[absolute path to backup destination]/$HOST" | |
# http://qiita.com/usagimaru/items/134a4ed0642e1f9ae1e7 | |
SOURCE="${1%/}" | |
DESTINATION="${2%/}/$HOST" | |
EXCLUDEDFILES="${3%/}" | |
# --- Main Program --- # | |
# Create destination if it does not exist | |
if [[ ! -d "$DESTINATION" ]] ; then | |
mkdir -p "$DESTINATION" | |
fi | |
# Make inital backup if Latest does not exist, otherwise only copy what has changed | |
# and hard link to files that are the same | |
if [[ ! -L "$DESTINATION"/Latest ]] ; then | |
rsync $RSYNC_OPTIONS \ | |
--delete \ | |
--exclude-from=$EXCLUDEDFILES \ | |
"$SOURCE" "$DESTINATION"/$DATE_FORMAT | |
else | |
rsync $RSYNC_OPTIONS \ | |
--delete \ | |
--delete-excluded \ | |
--exclude-from=$EXCLUDEDFILES \ | |
--link-dest="$DESTINATION"/Latest \ | |
"$SOURCE" "$DESTINATION"/$DATE_FORMAT | |
fi | |
# Remove symlink to previous Latest backup | |
rm -f "$DESTINATION"/Latest | |
# Create symlink to latest backup | |
ln -s $DATE_FORMAT "$DESTINATION"/Latest | |
# --- Remove old backups --- # | |
# BSD date in OS X has a different syntax than GNU date in Linux | |
if [[ $OS == "Darwin" || $OS == "FreeBSD" ]]; then | |
# Return YYYY one year ago from today | |
LAST_YEAR=$(date -v -1y "+%Y") | |
elif [[ $OS == "Linux" ]]; then | |
# Return YYYY one year ago from today | |
LAST_YEAR=$(date -d "last year" "+%Y") | |
fi | |
# Keep monthly backups for one year | |
for (( month = 1 ; month < $CURRENT_MONTH ; month++ )); do | |
# List latest backup from each month of current year | |
# Use printf to pad the single digit months with a 0 | |
LATEST_BACKUP=$(find "$DESTINATION" -mindepth 1 -maxdepth 1 -name ${CURRENT_YEAR}-$(printf "%02d" $month)-* | sort | tail -n 1) | |
find "$DESTINATION" -mindepth 1 -maxdepth 1 -name ${CURRENT_YEAR}-$(printf "%02d" $month)-* | grep -v "$LATEST_BACKUP" | xargs -I {} rm -rf {} | |
done | |
for (( month = $CURRENT_MONTH ; month <= 12 ; month++ )); do | |
# List latest backup from each month of current year | |
# Use printf to pad the single digit months with a 0 | |
LATEST_BACKUP=$(find "$DESTINATION" -mindepth 1 -maxdepth 1 -name ${LAST_YEAR}-$(printf "%02d" $month)-* | sort | tail -n 1) | |
find "$DESTINATION" -mindepth 1 -maxdepth 1 -name ${LAST_YEAR}-$(printf "%02d" $month)-* | grep -v "$LATEST_BACKUP" | xargs -I {} rm -rf {} | |
done | |
# Remove backups older than one year | |
for (( month = 1 ; month < $CURRENT_MONTH ; month++ )); do | |
find "$DESTINATION" -mindepth 1 -maxdepth 1 -type d -name "$LAST_YEAR-$(printf "%02d" $month)-*" | xargs -I {} rm -rf {} | |
done | |
find "$DESTINATION" -mindepth 1 -maxdepth 1 -type d ! -name "$CURRENT_YEAR-*" | grep -v "$LAST_YEAR-*" | xargs -I {} rm -rf {} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment