Requirements:

  • Backup must not be automatic. I want to chose whether and when to back up because the drive can be plugged out.
  • Backup must be to an AFP share in my local network.
  • Backup must be done with one click (or one command).

I have an (encrypted) external hard drive that I use for photos and other stuff, that doesn’t fit on my MacBook Air, that needs to be backed up. I know I can use Apple’s Time Machine to also back up external drives but I somehow feel safer when the backup is readable. So I want some rsync-type-of backup solution. I tried a couple of GUI sync apps but every one had a major flaw. It needed me to mount the backup location manually. That means that backing up always involved two steps. Actually four - mounting the network drive, opening the app, pressing a button, umounting.

So I decided to write a bash script that does all this for me.

  1. Mount the AFP share
  2. Synchronise the files of the external hard drive to the AFP share
  3. Detach the ADF share

And here is the script.

dir=$1
afp_url=$2

afp_url_arr=(${afp_url//\// })

domain=${afp_url_arr[1]}
volume=${afp_url_arr[2]}

mountpoint=/Volumes/$volume

mkdir $mountpoint

if [[ $domain == *"@"* ]]
then
  mount_afp -i $afp_url $mountpoint
else
  user=$USER
  pwd=$(security 2>&1 >/dev/null find-internet-password -gs $domain -a $user | ruby -e 'print $1 if STDIN.gets =~ /^password: "(.*)"$/')

  if [ -n "$pwd" ]
  then
    mount_afp ${afp_url/\/\//\/\/$user:$pwd@} $mountpoint
  else
    mount_afp -i $afp_url $mountpoint
  fi
fi

rsync -aP --delete --exclude=.DS_Store --exclude=.afpDeleted* $dir/ $mountpoint

umount $mountpoint

It requires two parameters, $1, the directory you want to back up and $2, the AFP URL. Then it extracts the domain and volume from the URL. So for example for the URL afp://192.168.0.1/MyDirectoryBackup the domain would be 192.168.0.1 and the volume MyDirectoryBackup.

The domain is needed to check the OS X Keychain for a password because this is usually stored by domain. The volume is needed to create a directory with that name in the /Volumes folder because this is how OS X does it if you mount it through Finder.

After creating the directory it checks whether a username and password is provided in the URL. If not it will try to get one from Keychain and add it to the URL. If credentials are already provided or no Keychain password was found, it will use the mount_afp -i flag that will prompt the user for a password.

Then rsync is executed with the archive, partial, progress and delete flag. Also some not needed files are excluded.

At the end the AFP share is detached.

I’ve also created an alias in my .bash_profile so I can execute it without parameters.

alias backup="/Users/vicox/Applications/backup-to-afp.sh /Volumes/MyDrive afp://192.168.0.1/MyDriveBackup"

The script can be found on Github: https://github.com/vicox/backup-to-afp.sh