A Launchd.plist generator for passwordless rsync (and anything else!)

I was trying to figure out how to configure rsync to run on a schedule on my Mac. My goal was to backup my laptop’s Documents directory to an Ubuntu instance running in the lab. (My employer doesn’t support Macs very well. They have automatic backups for Windows laptops. Mac users are left to their own best effort.)

Rsync is a great option. When used in archive mode (-a) it conserves bandwidth by only sending changes over the wire. Sweet. The command I use is:

rsync -av -e ssh ~/Documents/ user@10.10.10.10:/home/user/backup/

Note the use of the ‘-e’ option to tell rsync to use ssh. I have copied my ssh public key to /home/user/.ssh/authorized_keys on the destination server. This allows rsync to run without requiring a password.

As I read through the options for scheduling on the Mac, launchd seemed to be the best choice for me. Configuration of launchd is both simple and complex. Simple because the creation of a plist file in ~/Library/LaunchAgents is all you need. Complex because the syntax of the plist file is powerful and potentially tedious. I didn’t find any “launchd for dummies” sites. Most sites I found repeated the same example. I wanted more.

Then I foundĀ http://launched.zerowidth.com/. This *very* useful site presents a form to fill out, then produces your plist file, and finally provides instructions for copying the plist file to your system and configuring launchd to use it immediately. The form takes the guesswork out of the scheduling portion of the configuration. Double sweet.

Here’s a screenshot of the Basics for running my backup job at noon on Monday, Wednesday and Friday each week:

Screen Shot 2016-05-23 at 11.34.44 AM

The screen, above, produces the following plist file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>com.zerowidth.launched.backup</string>
	<key>ProgramArguments</key>
	<array>
		<string>sh</string>
		<string>-c</string>
		<string>rsync -av -e ssh ~/Documents/ user@10.10.10.10:/home/user/backup/</string>
	</array>
	<key>StartCalendarInterval</key>
	<array>
		<dict>
			<key>Hour</key>
			<integer>12</integer>
			<key>Minute</key>
			<integer>0</integer>
			<key>Weekday</key>
			<integer>1</integer>
		</dict>
		<dict>
			<key>Hour</key>
			<integer>12</integer>
			<key>Minute</key>
			<integer>0</integer>
			<key>Weekday</key>
			<integer>3</integer>
		</dict>
		<dict>
			<key>Hour</key>
			<integer>12</integer>
			<key>Minute</key>
			<integer>0</integer>
			<key>Weekday</key>
			<integer>5</integer>
		</dict>
	</array>
</dict>
</plist>

I found that looking at the plist output was very helpful in understanding the syntax.