Auto-backup a USB drive

No apologies for how infrequently I blog here – if you look carefully online you’ll find I have another blog that is all about my teaching of Computing.

This post is another solution for linux that may be helpful to others. Like many people, my wife uses a USB stick to transfer files she’s been working on to different computers in different classrooms she’s teaching in at school – and to bring them home to work on too. After losing work once too often through disk failure, I decided I needed to get a backup solution that was entirely transparent for her but worked every time.

The obvious thing is to take a copy of the disk each time it’s plugged into the Ubuntu PC at home and then let my Crashplan backup do the rest. Making this automatic was a little more tricky than I expected!

As I know rsync I’ll use that to move files across to a folder in her user area. Easy.

First I tried using udev to trigger it, It took me a while to test this fully, but my final conclusion was that because the script had to complete before the disk was handed off to another service to mount, that was a dead-end for me.

I had written a pretty full script for checking it’s the correct disk and where it’s mounted by this point, so I found in my research something called devmon which is now part of udevil. This allows me to run a script whenever a new disk is mounted – and since my code already checks for the correct disk before running any backup, that’s all good.

I made the devmon command to run on startup for all users, too – creating a startup .desktop through the gui with this command:

devmon --exec-on-drive "/home/jane/Programs/jane-usb.sh"

This is the script it launches any time any drive is mounted. It will only sync if the right drive is present, using UUID.

#!/bin/bash
started=`date`
#this is the UUID as found by running mount and blkid then looking for the right device
usbdisk='8553-6FF8'
sleep 0
if [ $(blkid | grep -c 8553-6FF8) = 1 ]; then
 mydev="$(blkid -l -o device -t UUID=$usbdisk)"
 echo "Device $mydev available"
#I had an issue with it running before mount was complete. This loop will make sure it's properly mounted before running rsync
waitTime=0
 while [[ $(mount | grep -c $mydev) != 1 && $waitTime -lt 5 ]]; do
 sleep 1
 echo $waitTime
 ((waitTime++))
 done
 #if the correct device isn't mounted we'll sync, otherwise end
 if [ $(mount | grep -c $mydev) = 1 ]; then
   mnt="$(mount | grep $mydev | cut -d ' ' -f 3)"
   echo "Mounted at _$mnt _"
   rsync -ax --delete $mnt/ /home/jane/usb
 else
   exit 1
 fi
else
 exit 1
fi
echo Backup done, started at $started, finished at `date`
echo Backup done, started at $started, finished at `date`>>/home/jane/Programs/jane-usb.log