Skip to content

Instantly share code, notes, and snippets.

@kevinkirkup
Last active December 17, 2015 05:28
Show Gist options
  • Save kevinkirkup/5557770 to your computer and use it in GitHub Desktop.
Save kevinkirkup/5557770 to your computer and use it in GitHub Desktop.
Timemachine script to mount TimeMachine backup disk and trigger a time machine backup.Had to make some modifications to put in in the OSX standard log location.Reference:http://hints.macworld.com/article.php?story=20100712085231232
#!/usr/bin/env python
# place in /etc/periodic/daily to run nightly (or hourly if set up):
#
# sudo cp -f timemachine.py /etc/periodic/daily/667.timemachine
# sudo cp -f timemachine.py /etc/periodic/hourly/667.timemachine
import re
import datetime
import time
from subprocess import Popen, PIPE
# do executes a shell command, returning stdout and stderr
def do(cmd):
p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
(fi, fo, fe) = (p.stdin, p.stdout, p.stderr)
fi.close()
msg = fo.read()
fo.close()
fe.close()
return msg
# mounted checks if vol is mounted
def mounted(vol):
pat = r'/Volumes/(\S+)\s+[(](.+)[)]'
msg = do('/sbin/mount')
vols = dict(re.compile(pat).findall(msg))
return vol in vols.keys()
# disks returns a dictionary associating e.g. 'Flash' to 'disk0s2'
def disks():
pat = r'Apple_HFS\s+(\S+)\s+.+(disk\d+s\d+)'
msg = do('/usr/sbin/diskutil list')
vols = re.compile(pat).findall(msg)
return dict(vols)
# sleep waits a bit
def sleep():
time.sleep(30)
# mount_volume returns pair (now mounted?, was mounted?),
# after attempting to mount volume for "name" as needed
def mount_volume(vol, logfile):
if mounted(vol):
(now, was) = (True, True)
else:
was = False
diskID = disks()
mountable = diskID.keys()
if vol in mountable:
do("/usr/sbin/diskutil mount %s >>'%s' 2>&1" % (diskID[vol], logfile))
sleep()
now = mounted(vol)
return (now, was)
# unmount_volume unmounts volume
def unmount_volume(vol, logfile):
do("/usr/sbin/diskutil unmount '/Volumes/%s' >>'%s' 2>&1" % (vol, logfile))
# run Time Machine
# Time Machine has finished when 'backupd' is no longer running
logdir = '/Library/Logs/Backup Logs'
backupd = "/System/Library/CoreServices/backupd.bundle/Contents/Resources/backupd-helper >>'%s' 2>&1"
def start_backupd(logfile):
do("echo 'starting Time Machine' >>'%s'" % logfile)
do(backupd % logfile)
def backupd_running(logfile):
return do("ps -ax | grep [b]ackupd >>'%s' 2>&1" % logfile)
def timemachine(vol):
now = datetime.datetime.now().strftime("%F %H-%M-%S")
logfile = "%s/%s (Time Machine)" % (logdir, now)
(tnow, twas) = mount_volume(vol, logfile)
if tnow:
start_backupd(logfile)
sleep()
while backupd_running(logfile):
sleep()
if not twas:
sleep()
for i in range(1,8):
sleep()
unmount_volume(vol, logfile)
if not mounted(vol):
break
# execute (replace 'Time' by name of Time Machine volume)
timemachine('TimeMachine')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment