SuperDuper! scripts

I recently installed Leopard on my work computer (an Intel iMac) and upgraded SuperDuper to the Leopard-compatible version 2.5. I have SuperDuper set up to backup the iMac every weeknight. For the most part, this has worked well, but on two occasions the backup failed because SuperDuper couldn’t find the backup disk. Happily, GeekTool told me that the backup didn’t work (and, er, SuperDuper stayed open with red letters all over the place, so maybe my GeekTool script isn’t necessary), and I think I now have a permanent solution to the problem.

Let me first say that failing to find the backup disk wasn’t SuperDuper’s fault. I keep my backup disk unmounted to prevent inadvertent data loss, mounting it only during the backup itself. SuperDuper’s scheduler has the ability to run scripts before and after the backup, and I use this to mount the disk before the backup and unmount it after.

The shell command for mounting a disk is pretty simple. Here’s an example:

diskutil mount disk0s3

The disk0s3 is the device file for a particular partition on a particular disk. Device files are an old Unixism; one of Unix’s big ideas was to make everything look like a file so reading and writing to a hardware device (like a disk or a serial port) is as simple as reading and writing to a file. Device files are kept in the /dev directory, and if you run ls /dev/disk*, you’ll see a few of these device files.

The problem with mounting the backup disk is knowing which one of these device files corresponds to that disk. When I first started using SuperDuper, I ran Disk Utility and clicked the Info button to learn that the backup disk was disk3s10. I then made a shell script, called “mount_backup,” that ran diskutil with that device and had SuperDuper call it before starting the backup. A similar script, called “unmount_backup,” was called after the backup. This worked perfectly for months.

The first backup I tried after the change to Leopard and the upgrade to SuperDuper failed because the device file changed and the mounting script failed. No problem, I thought, I’ll just get the new device file and put it into the mount and unmount scripts. That worked for a few days, and then there was another failure because the device file had changed again.1 Clearly, I needed something more foolproof.

It turns out that diskutil can do more than mount and unmount disks. If you run diskutil list, you’ll get something like this:

   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     Apple_partition_scheme                        *74.5 Gi    disk0
   1:        Apple_partition_map                         31.5 Ki    disk0s1
   2:                  Apple_HFS HD                      74.4 Gi    disk0s3

This is the output I just got running the command on my iBook, which is the computer I’m in front of right now. The lines refer to the internal hard disk and its partitions. The only partition that can be mounted is the last one, with the name “HD” and the device file “disk0s3.” If you’re working at a computer with an external drive plugged in, you’ll get a set of lines for that drive, and the only mountable partitions will be the ones with names. Since the name of my backup disk is “Backup,” I can figure out its device file by looking at the last field in the line that has “Backup” in its third field. An easy job for awk.

So here’s the new version of mount_backup:

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

Line 3 gets the list of partitions and filters it through awk to get the device file corresponding to my backup disk. Line 4 then mounts that disk; because diskutil’s mount command spits out a line of diagnostic info that’s of no use to me, I redirect the output to /dev/null.

The unmount_backup script is the same, but with two more letters in Line 4:

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

Now my scripts are smart enough to handle changes in the backup disk’s device file.

I should mention that if you want to adapt these scripts for your own needs, the adaptation will be much simpler if

  1. The name of your backup disk has no spaces. Awk uses spaces to separate fields, and if your disk name has spaces the device file will not be in the sixth field.
  2. None of the names of your other disks start with the name of your backup disk. If, for example, you have two backup disks, one named “Backup” and the other named “Backup weekly,” awk will grab info from the lines corresponding to both of those disks, and the mount command will fail.

  1. I have no idea why the device file would change. In Linux, the device files for hard disks on the IDE bus are named according to their position on the bus and the partition number—physical facts that don’t change unless you remove the drive and reinstall it in a different location.