Last active
August 29, 2015 14:01
-
-
Save gandalfx/9235ddc636511015a087 to your computer and use it in GitHub Desktop.
Minecraft Saves Backup Manager (can be used for other stuff as well)
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 | |
set -e | |
help_text=' | |
McBackup creates and manages backups of your Minecraft game saves. | |
Game saves are expected to be stored in ~/.minecraft/saves. | |
Backups are stored in ~/.minecraft/backups by default. | |
To change this edit the $mcdir and $backupdir variables. | |
McBackup will manage multiple copies of varying age of each game save. | |
Old backups will be discarded incrementally. | |
Usage: | |
/path/to/mcbackup.sh [OPTIONS] [SAVES] | |
OPTIONS See below | |
SAVES Can be a list of names of game saves to be backed up. | |
May be omitted if the -a option is used (see below). | |
The name of the directory inside $mcdir/saves/ is relevant. | |
Note that this may not be identical to the name displayed in-game. | |
Saves that do not have a corresponding directory inside the | |
$backupdir/ will be skipped unless the -f switch is specified. | |
Options: | |
-a Backup all saves that are inside $mcdir/saves/. | |
If used with -d, process all backups inside $backupdir/ | |
(regardless of whether they exist inside $mcdir/saves/) | |
-d Discard only. Do not create new backups but check existing ones for | |
obsolete versions | |
-f Force backup creation. If a save does not have a corresponding | |
directory inside $backupdir/ that directory will be created. | |
-h Show this help text and exit. | |
-n No discarding. Only create backups, do not check if any are outdated. | |
Created by Gandalfx | |
https://gandalfx.github.com | |
' | |
################ | |
### settings ### | |
################ | |
mcdir="$HOME/.minecraft" | |
backupdir="$HOME/.minecraft/backups" | |
################# | |
### functions ### | |
################# | |
# creates a new backup if possible and necessary | |
# param 1 is save's (base)name | |
function update_backup { | |
local save="$(basename "$1")" | |
if [[ ! -d "$mcdir/saves/$save" ]] ; then | |
echo "skipping '$save'..." | |
return | |
fi | |
echo -en "checking $bold$blue$save$end: " | |
if [[ ! -d "$backupdir/$save" ]] ; then | |
if $flag_force ; then | |
echo -e "${green}creating backup at '$backupdir/$save'..." | |
mkdir -p "$backupdir/$save" | |
else | |
echo -e "$red'$backupdir/$save' doesn't exist!$end skipping..." | |
return | |
fi | |
fi | |
if [ ! -e "$backupdir/$save/latest" ] || | |
[[ $(diff -rq "$mcdir/saves/$save" "$backupdir/$save/latest") != "" ]] | |
then | |
echo -e "${red}backup outdated!$end" | |
local today=$(date +%F) | |
echo "syncing files..." | |
rsync -a --delete "$mcdir/saves/$save/" "$backupdir/$save/$today" | |
ln -snf "$backupdir/$save/$today" "$backupdir/$save/latest" | |
$flag_no_discard || discard_old_backups "$backupdir/$save" | |
else | |
echo -e "${green}up to date$end" | |
fi | |
} | |
# manages old saves | |
# param 1 is path containing saves | |
function discard_old_backups { | |
pushd . > /dev/null | |
cd "$1" | |
local saves=(*-*-*) # format is yyyy-mm-dd | |
unset saves[${#saves[@]}-1] # always keep youngest save | |
unset days week month year # steps | |
for save in "${saves[@]}" ; do | |
# echo "found save $save" | |
if [[ $save < $(date +%F -d "1 year ago") ]] ; then | |
# $save is older then a year | |
# -> keep youngest | |
if [[ $year ]] ; then | |
rm -r $year | |
echo "removed old save '$PWD/$year'" | |
fi | |
local year=$save | |
elif [[ $save < $(date +%F -d "1 month ago") ]] ; then | |
# $save is older then a month but younger then a year | |
# -> keep oldest | |
if [[ $month ]] ; then | |
rm -r $save | |
echo "removed old save '$PWD/$save'" | |
else | |
local month=$save | |
fi | |
elif [[ $save < $(date +%F -d "1 week ago") ]] ; then | |
# $save is older then a week but younger then a month | |
# -> keep oldest | |
if [[ $week ]] ; then | |
rm -r $save | |
echo "removed old save '$PWD/$save'" | |
else | |
local week=$save | |
fi | |
elif [[ $save < $(date +%F -d "2 days ago") ]] ; then | |
# $save is older then 2 days but younger then a week | |
# -> keep oldest | |
if [[ $days ]] ; then | |
rm -r $save | |
echo "removed old save '$PWD/$save'" | |
else | |
local days=$save | |
fi | |
fi | |
done | |
popd > /dev/null | |
} | |
########### | |
### run ### | |
########### | |
# use colors only for terminal output | |
if [[ -t 1 ]] ; then | |
red="\e[91m" | |
blue="\e[34m" | |
green="\e[32m" | |
bold="\e[1m" | |
end="\e[0m" | |
fi | |
# parse flags | |
flag_all=false | |
flag_force=false | |
flag_no_discard=false | |
flag_discard_only=false | |
while getopts "afndh" opt ; do | |
case "$opt" in | |
a) flag_all=true;; | |
f) flag_force=true;; | |
n) flag_no_discard=true;; | |
d) flag_discard_only=true;; | |
h) printf "$help_text"; exit;; | |
*) exit 1;; | |
esac | |
done | |
# remove flags from parameter list | |
shift $(($OPTIND - 1)) | |
if $flag_discard_only ; then | |
$flag_all && saves=( "$backupdir/"* ) || saves=( $@ ) | |
[[ $saves ]] || echo "no saves specified!" | |
for save in "${saves[@]}" ; do | |
save="$(basename "$save")" | |
if [[ -d "$backupdir/$save" ]] ; then | |
discard_old_backups "$backupdir/$save" | |
else | |
echo "'$save' has no backups." | |
fi | |
done | |
else | |
$flag_all && saves=( "$mcdir/saves/"* ) || saves=( $@ ) | |
[[ $saves ]] || echo "no saves specified!" | |
for save in "${saves[@]}" ; do | |
update_backup "$save" | |
done | |
fi | |
### an old friend | |
# for age in saves_2*; do for sav in $age/* ; do mkdir -pv "backups/$(basename "$sav")" && cp -ru "$sav" "backups/$(basename "$sav")/${age#saves_}"; done; done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment