Any way to automate a Time Machine backup, mount-backup-unmount?

Ok, so I had this mostly written already.

Save this file as /usr/local/bin/timemachine-mount-run-unmount.sh

#!/usr/bin/env zsh -f
# Purpose: 	Once you set the DEVICE,
#			this script will mount your Time Machine drive,
#			run Time Machine,
#			and then unmount the drive
#
# From:	Timothy J. Luoma
# Mail:	luomat at gmail dot com
# Date:	2020-04-20

	## To find the device, mount the Time Machine drive and then run this command in Terminal:
	#
	#	mount | egrep '^/dev/' | sed -e 's# (.*#)#g' -e 's# on /# (/#g'
	#
	# and you will see a bunch of entries like this
	#
	#	/dev/disk2s1 (/Volumes/MBA-Clone - Data)
	#	/dev/disk3s5 (/Volumes/Storage)
	# 	/dev/disk4s6 (/Volumes/MBA-Clone)
	#
	# You need to set
	#
	#	DEVICE='/dev/disk3s5'
	#
	# or whatever is correct for your Time Machine drive

DEVICE=''




################################################################################################

NAME="$0:t:r"

if [[ -e "$HOME/.path" ]]
then
	source "$HOME/.path"
else
	PATH="$HOME/scripts:/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin"
fi

zmodload zsh/datetime

TIME=$(strftime "%Y-%m-%d--%H.%M.%S" "$EPOCHSECONDS")

function timestamp { strftime "%Y-%m-%d--%H.%M.%S" "$EPOCHSECONDS" }

STATUS=$(tmutil currentphase)

if [[ "$STATUS" != "BackupNotRunning" ]]
then
	echo "$NAME: Time Machine status is '$STATUS'. Should be 'BackupNotRunning'." >>/dev/stderr
	exit 0
fi

	# if you have multiple Time Machine destinations, this might not give you the right info
	# I'm assuming you only have one
TM_DRIVE_NAME=$(tmutil destinationinfo | egrep '^Name  ' | sed 's#^Name  *: ##g' | head -1)

MNTPNT="/Volumes/$TM_DRIVE_NAME"

if [[ -d "$MNTPNT" ]]
then

	echo "$NAME: '$MNTPNT' is already mounted".

else


	if [[ "$DEVICE" == "" ]]
	then
		echo "$NAME: the 'DEVICE' variable is not set" >>/dev/stderr
		exit 0
	fi

	diskutil mountDisk "$DEVICE"

fi

if [[ ! -d "$MNTPNT" ]]
then

	echo "$NAME: Failed to mount '$MNTPNT'." >>/dev/stderr
	exit 0
fi

TM_DRIVE_ID=$(tmutil destinationinfo | egrep '^ID  ' | sed 's#^ID  *: ##g' | head -1)

echo "$NAME: Starting backup at `timestamp`"

	# `caffeinate -i` is optional but keeps your Mac from sleeping
caffeinate -i tmutil startbackup --block --destination "$ID"

EXIT="$?"

if [[ "$EXIT" == "0" ]]
then
	echo "$NAME: Finished successfully at `timestamp`."

else

	echo "$NAME: Finished UN-successfully (Exit = $EXIT) at `timestamp`."

fi

while [[ -d "$MNTPNT" ]]
do

		# this will try to unmount the drive as long as it is mounted

	diskutil unmountDisk "$MNTPNT"

	sleep 10

done

exit 0
#EOF

Note that the file is probably not fully shown in your browser, so be sure you copy the whole thing.

Note that you need to run the command:

mount | egrep '^/dev/' | sed -e 's# (.*#)#g' -e 's# on /# (/#g'

and then set the DEVICE='' variable near the top of the file.

Failure to do this will cause this script to inevitably fail.

Make Executable (Mandatory)

Once the file is saved in its location, make sure it is executable:

chmod 755 /usr/local/bin/timemachine-mount-run-unmount.sh

Try it

Once you have done all of that, you can run the script like this:

/usr/local/bin/timemachine-mount-run-unmount.sh

and it should tell you what it is doing.

Optional - launchd daily operation

If you want to have this run automatically every day. save the file below as:

$HOME/Library/LaunchAgents/com.tjluoma.timemachine-mount-run-unmount.plist

Here’s the file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>com.tjluoma.timemachine-mount-run-unmount</string>
	<key>Program</key>
	<string>/usr/local/bin/timemachine-mount-run-unmount.sh</string>
	<key>RunAtLoad</key>
	<true/>
	<key>StandardErrorPath</key>
	<string>/tmp/com.tjluoma.timemachine-mount-run-unmount.log</string>
	<key>StandardOutPath</key>
	<string>/tmp/com.tjluoma.timemachine-mount-run-unmount.log</string>
	<key>StartCalendarInterval</key>
	<dict>
		<key>Hour</key>
		<integer>1</integer>
		<key>Minute</key>
		<integer>5</integer>
	</dict>
</dict>
</plist>

Once you have that file in place, do this in Terminal (all one line):

launchctl load "$HOME/Library/LaunchAgents/com.tjluoma.timemachine-mount-run-unmount.plist"

You can look at the log file at /tmp/com.tjluoma.timemachine-mount-run-unmount.log to see if it works.

Note that the way that I have it, it will run:

  1. Whenever you log in

  2. Every dat at 1:05 a.m.

The idea here is that you might want to make sure that it runs every day when you aren’t using the computer (maybe? No judgment.)

Questions?

Let me know.

2 Likes