Skip to content

Instantly share code, notes, and snippets.

@rolux
Last active March 5, 2020 11:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rolux/acfa1f4d7a481988ab69da1d730e9687 to your computer and use it in GitHub Desktop.
Save rolux/acfa1f4d7a481988ab69da1d730e9687 to your computer and use it in GitHub Desktop.
docstring = '''
backup.py
Time Machine-style backup for external drives.
Usage:
> python3 backup.py "/Volumes/My Drive" "/Volumes/My Backup Drive"
Optional:
> python3 backup.py "/Volumes/My Drive" "/Volumes/My Backup Drive" exclude.txt
'''
import os
import sys
import time
def escape(string):
return string.replace(' ', '\\ ')
if len(sys.argv) < 3:
sys.exit(docstring)
src, dst = sys.argv[1], sys.argv[2]
dst = os.path.join(dst, 'Backups', os.path.basename(src))
os.makedirs(dst, exist_ok=True)
src, dst = escape(src), escape(dst)
exclude = f'--exclude-from={escape(sys.argv[3])} ' if len(sys.argv) == 4 else ''
time_format = '%Y-%m-%d-%H%M%S'
date = time.strftime(time_format, time.localtime())
in_progress = f'{dst}/{date}.inProgress'
latest = f'{dst}/Latest'
latest_relative = latest.replace(dst, '..')
command = ' && '.join([
f'rsync -hazP --delete --delete-excluded {exclude}'
+ f'--link-dest={latest_relative} {src} {in_progress}',
f'date=`date "+{time_format}"`',
f'mv {in_progress} {dst}/$date'
f'rm -f {latest}',
f'ln -s $date {latest}'
])
print(command)
os.system(command)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment