Automatic Backups to USB Flash Drives

I do a lot of my study and note-taking in the library. Unfortunately my library doesn’t offer wireless printing. Instead I have to copy my work to my flash drive, go to one of the Windows terminals in the library, open my files from the USB drive and print my work from there. I have been looking for a way to automate this process. That is when I came across Constantinos Neophytou’s script on the Voodoo Programming blog. But that script was doing the opposite of what I was looking for. It was a script to backup the contents of your flash drive onto your Mac. I wanted to backup folders from my Mac onto my flash drive.

So I used a lot of Constantinos’ code and with his help (and a lot of trial and error) created the automatic backup to USB thumb drive script below.

What I like about the script is that it doesn’t require any third-party applications, runs in the background and is customizable (you can have different backup scripts on different thumb drives backing up different folders).

How Does It Work?

When I mount my USB drive on my Mac the script automatically copies four folders (that I have set in the code) from my Mac onto my USB drive. These four folders are my “working” folders – they contain my class and study notes. Now I will always have an exact copy of my most important university files on my USB drive.

Set-Up

First of all we have to set up a folder-action. The folder-action scans the root folder of the mounted volume and looks for a specified file name (in this case rsync.app).


(* Wait for drive to mount *)
delay 5

property backup_scripts : {"rsync.app"} (* add/change this list to match the name(s) of your script(s) *)

on adding folder items to this_folder after receiving these_volumes
	tell application "Finder"
		try
			set the volume_list to every file of this_folder

			(* go through all entries in /Volumes/ *)
			repeat with i from 1 to number of items in volume_list
				set this_item to the original item of item i of volume_list
				if the kind of this_item is "Volume" then
					set this_disk to (this_item as alias)

					(* is this item the newly mounted disk? *)
					if this_disk is in these_volumes then

						(* iterate through all files in the root of disk *)
						set the file_list to every file of item i of volume_list
						repeat with j from 1 to number of items in file_list

							(* check to see if a backup script is available *)
							set this_file to name of item j of file_list
							if this_file is in backup_scripts then
								open item j of file_list (* run the backup script *)
							end if
						end repeat
					end if
				end if
			end repeat
		on error error_message number error_number
			if the error_number is not -128 then
				display dialog error_message buttons {"OK"} default button 1
			end if
		end try
	end tell
end adding folder items to

To apply the folder action do the following.

  1. Copy the above code in Script Editor (generally located in Applications/AppleScript/)
  2. Save it as a script in /Library/Scripts/Folder Action Scripts/, and give it a descriptive name (e.g. Auto Backup.scpt)
  3. In Finder, click Go -> Go to Folder (or just press cmd-shift-G), and type /Volumes/.
  4. Launch the Folder Actions Setup utility (generally located in /Applications/AppleScript/)
  5. Click the Add Folder Action (round plus) button at the bottom left
  6. Drag the small folder icon from the Finder window title bar into the Choose Folder sheet dialog, and click Open.
  7. From the dialog that comes up, chose the script you just saved.
  8. You’re done.

Now for the backup script.

(*
	Automatic Backup *to* Flash Drive v1 by Mark Fisher
	Most of the code comes from Constantinos C. Neophytou's
	"Automating backup of Flash drives" ~

http://www.cneophytou.com/2007/03/06/automating-backup-of-flash-drives/

*)

property with_administrator_privileges : false

property display_notification : true

property eject_after_backup : true

property rsync_params : "-aEz --delete-excluded"
(* END OF PREFERENCES *)

set WhereImRunningFrom to path to me
tell application "Finder"
	(* can't run from the script editor *)
	set AppCreator to creator type of WhereImRunningFrom
	if AppCreator is "ToyS" then
		activate of me
		beep
		display alert "This script cannot run directly from ScriptEditor"
		return
	end if

	(* NEVER run from the hard drive! *)
	set bootVolume to name of disk of home (* safety feature! *)
	set NameOfDisk to name of disk of WhereImRunningFrom
	if NameOfDisk is bootVolume then
		beep
		display alert "Should not run this script from the boot volume!"
		return
	end if

	(* set folders to be backed up. *)
	-- AppleScript doesn't really have arrays. Instead create a "list" of folders to be backed up.
	-- Code from: http://lists.apple.com/archives/AppleScript-Users/2005/Dec/msg00475.html
	set backup_folders to {"/Users/markfisher/Desktop/Inbox", "/Users/markfisher/_LawSchool 2008 Sem 1", "/Users/markfisher/Desktop/Pending", "/Users/markfisher/Desktop/Outbox"}

	(* find target *)
	set targetDir to quoted form of ("/Volumes/" & NameOfDisk & "/")

	-- Use AppleScript Repeat Loops
	-- Code from: http://www.Mactech.com/articles/Mactech/Vol.20/20.12/RepeatLoops/index.html
	-- Loops through each item in backup_folders and copies it to the targetDir
	repeat with theCurrentValue in backup_folders

		(* find source *)
		-- each time the code loops, the variable theCurrentValue will take on the value
		-- of the current item in the list variable backup_folders
		set sourceDir to quoted form of ("/Volumes/" & name of disk of home & theCurrentValue)

		(* do the backup *)
		(* try *)
		if with_administrator_privileges then
			set excluded to " "
		else
			set excluded to " --exclude='.Trash*' --exclude='.Spotlight*'  "
		end if

		set theScript to "rsync " & rsync_params & excluded & sourceDir & " " & targetDir & "; touch " & targetDir

		if with_administrator_privileges then
			do shell script theScript with administrator privileges
		else
			do shell script theScript
		end if

	end repeat

end tell

activate of me
beep
if display_notification then display alert "Backup to " & NameOfDisk & " complete."
(*
on error
    display alert "There was an error backing up to " & NameOfDisk
end try
*)

if eject_after_backup then
	display dialog "Eject " & NameOfDisk & " ?" buttons ["Cancel", "OK"]
	if button returned of result is "OK" then
		delay 5
		tell application "Finder"
			try
				eject NameOfDisk
				(* on error
				display alert "Error ejecting " & NameOfDisk
				return
				*)
			end try
		end tell
	end if
end if

Copy the above code into Script Editor (generally located in Applications/AppleScript/). Save it onto your flash drive as an Application bundle giving it the name rsync.

The part of the code that you have to modify is the "set backup_folders to …" parameter. In the code above I am backing up four folders – three folders from the Desktop (Inbox, Pending and Outbox) and one folder that hangs off my home directory: _LawSchool 2008 Sem 1.

You will have to alter your code accordingly. Make sure each folder is set relative to your home directory (e.g. /Users/YourHomeDirectory/) and that each folder path is enclosed in quotation marks and is separated by a comma. e.g. “/Users/janedoe/Documents/Law School”. If you don’t know what your home directory is called go to the Accounts preference pane in System Preferences and look for the Short Name version of your home directory.

A note about the preferences:

Once the backup has completed the eject_after_backup property asks you whether you want to eject the USB drive. You can turn this option off by setting the property to false.

The display_notification property tells you when the backup is completed. You can also turn this off by setting it to false.

Usage

Now you can drop a rsync application bundle onto any flash drive. You could have different flash drives containing backups of different folders from your Mac. You might have one flash drive that contains a backup of your study materials and another flash drive that contains a backup of your work files. This can all be done by simply altering the backup script.

Comments

View comments and add your own to this post (no registration required) in the Mac Law Students Forum.

This entry was posted in Techniques. Bookmark the permalink. Both comments and trackbacks are currently closed.