SuperDuper scripts in Mountain Lion

When I got my new iMac and began working with Mountain Lion for the first time, I found that one of the scripts I use in conjunction with my SuperDuper backups was generating an error and preventing my nightly backup from proceeding. I soon got things working again, and didn’t think any more of it until this tweet arrived yesterday.

@drdrang Using your SuperDuper (un)mount scripts - leancrew.com/all-this/2009/… - but getting dl.dropbox.com/u/1371905/Scre… - do they still work in ML?
jfield (@jfield) Mon Jan 28 2013 12:06 AM CST

Those scripts are so old, I didn’t think anyone else used them. Let me explain how I got my backups working again.

First, you should understand that I prefer having my backup disk unmounted except when the backing up is in progress. This keeps the backup safe from my inadvertent drags, drops, and double-clicks. SuperDuper needs the disk mounted to do its job, so I wrote a short shell script, called mount_backup to be called just before SuperDuper starts its work. And I wrote a similar script, unmount_backup, to tuck the backup disk away when SuperDuper is done. These scripts are called by SuperDuper itself, as specified in the Advanced options:

SuperDuper advanced settings

When I first wrote these scripts, Apple’s diskutil command wasn’t as smart as it is now (or maybe it was and I just wasn’t smart enough to realize it), and I had to go through a few manipulations to get the right argument to give it. Now, both mount_backup

bash:
1:  #!/bin/bash
2:  
3:  # BDISK=`/usr/sbin/diskutil list | awk '$3=="Backup" {print $6}'`
4:  # /usr/sbin/diskutil mount $BDISK > /dev/null
5:  
6:  /usr/sbin/diskutil mount Backup > /dev/null

and unmount_backup

bash:
1:  #!/bin/bash
2:  
3:  # BDISK=`/usr/sbin/diskutil list | awk '$3=="Backup" {print $6}'`
4:  # /usr/sbin/diskutil unmount $BDISK > /dev/null
5:  
6:  /usr/sbin/diskutil unmount Backup > /dev/null

are much simpler. “Backup” is the clever name I’ve given to my backup disk. I’ve kept the old code in there, commented out, in case diskutil stops being able to accept the name of the backup disk and I have to specify something like disk1s1 again.

When I started using Mountain Lion, SuperDuper would fail with an error message saying that the backup disk wasn’t mounted. I could see that SuperDuper was running mount_backup and I knew from testing at the command line that mount_backup worked, so this was a puzzler. One thing I did notice, though, was that sometimes mount_backup took a very long time to finish. If SuperDuper was running it asynchronously—starting its own process before mount_backup was done—that might explain the failure and the error message.

So I decided to set up a LaunchAgent that runs mount_backup a few minutes before SuperDuper is scheduled. The plist file, called com.leancrew.mount_backup.plist, looks like this:

xml:
 1:  <?xml version="1.0" encoding="UTF-8"?>
 2:  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 3:  <plist version="1.0">
 4:  <dict>
 5:    <key>Label</key>
 6:    <string>com.leancrew.mount_backup</string>
 7:    <key>ProgramArguments</key>
 8:    <array>
 9:      <string>/Users/drdrang/bin/mount_backup</string>
10:    </array>
11:    <key>StartCalendarInterval</key>
12:    <array>
13:      <dict>
14:        <key>Hour</key>
15:        <integer>21</integer>
16:        <key>Minute</key>
17:        <integer>25</integer>
18:        <key>Weekday</key>
19:        <integer>1</integer>
20:      </dict>
21:      <dict>
22:        <key>Hour</key>
23:        <integer>21</integer>
24:        <key>Minute</key>
25:        <integer>25</integer>
26:        <key>Weekday</key>
27:        <integer>2</integer>
28:      </dict>
29:      <dict>
30:        <key>Hour</key>
31:        <integer>21</integer>
32:        <key>Minute</key>
33:        <integer>25</integer>
34:        <key>Weekday</key>
35:        <integer>3</integer>
36:      </dict>
37:      <dict>
38:        <key>Hour</key>
39:        <integer>21</integer>
40:        <key>Minute</key>
41:        <integer>25</integer>
42:        <key>Weekday</key>
43:        <integer>4</integer>
44:      </dict>
45:      <dict>
46:        <key>Hour</key>
47:        <integer>21</integer>
48:        <key>Minute</key>
49:        <integer>25</integer>
50:        <key>Weekday</key>
51:        <integer>5</integer>
52:      </dict>
53:    </array>
54:  </dict>
55:  </plist>
56:  
57:  <!-- @@@@LingonWhatStart:/Users/drdrang/bin/mount_backup@@@@LingonWhatEnd --> 

As you can probably make out if XML doesn’t make your head swim with all the angled brackets, this causes the mount_backup script to run Monday through Friday at 9:25 pm. That’s five minutes before SuperDuper is scheduled to do its thing.

I’d like to say I wrote that plist file from scratch, but of course I didn’t. I used Lingon to both make it and load it.

Lingon

Unfortunately, Lingon doesn’t have options for scheduling scripts to run on Mondays through Fridays, so I started out by scheduling it for Monday only and then found the plist file in ~/Library/LaunchAgents and added the other <dict>s for Tuesday through Friday. And I’m pretty sure I had to add the <array> tags that wrap all the days together.

If you’re used to the crontab format for scheduling, the plist above will make you either laugh or cry. It’s incredibly verbose considering how little it does. But Apple wants us to use this instead of cron, and bucking Apple on things like this is never a good idea.

Scheduling mount_backup to run five minutes before SuperDuper did the trick. I haven’t seen any error messages since.