Most people in the IT industry are pretty concerned when dealing with backups. For my needs, I basically use just Dropbox (got a few GB for free when I bought a Samsung S3) + rsync.

After using only Dropbox for a while, I decided that I must have a redundant backup of my work. Something that would be closer to me physically, just in case Dropbox collapse or something… Well, I didn’t want to pay for it though.

So, if you are under a UNIX system, one way of achieving that (+ having incremental backups for free) is by using rsync.

My current set up is as following.

With Dropbox, I simply have symbolic links to backup all of my important stuff:

ln -s ~/Developer/projects ~/Dropbox/Backups/

For the rsync part I created a bash function that is loaded in my .bashrc:

function backup_my_stuff() {
  BACKUP_ORIGIN_PATH='/Users/foobar'
  BACKUP_DESTINATION_PATH='/Volumes/backups/'
  NOW=$(date +"%m-%d-%y-%T")
  LOG_PATH='rsync_backups'
  LOG_FILE="backup_$NOW.log"

  if [[ $(mount | \
    awk -v destination="$BACKUP_DESTINATION_PATH" '$3 == destination {print $3}') != "" ]]; then
    echo "Starting to backup..."
    [ -d $LOG_PATH ] || mkdir $LOG_PATH
    /usr/local/bin/rsync -aivz --delete-excluded --exclude=.DS_Store $BACKUP_ORIGIN_PATH \
    $BACKUP_DESTINATION_PATH > $LOG_PATH/$LOG_FILE 2>&1
    echo "Backup finished. Please check the log in ${LOG_PATH}/${LOG_FILE}"
  else
    echo "${BACKUP_DESTINATION_PATH} is not mounted. Aborting."
  fi
}

This function checks wether the volume is connected to my computer or not. If it’s, then it will create a folder for the backup logs and start “rsyncing”.

Let’s focus on the rsync part now:

/usr/local/bin/rsync -aivz --delete-excluded --exclude=.DS_Store \
$BACKUP_ORIGIN_PATH $BACKUP_DESTINATION_PATH > $LOG_PATH/$LOG_FILE 2>&1

The flags aivz essentially mean that it’s going to be recursive, copy symbolic links exactly as they are, preserve permissions/modification times/group/owners, output a change summary, be verbose and transfer all the data compressed (which, of course, is faster).

Next, I say that I want to delete from the destination files that have been deleted from the source and to remove any .DS_Store files generated by my Mac OS X.

The following commands are pretty self explanatory. To finish it, I send rsync’s output to a logfile, which is going to be named according to the current timestamp. I also send STDERR to STDOUT, to avoid errors being displayed in the terminal window.

That’s it.

If you wanna play further with it, a cool thing about using rsync is that I could easily plug in my external HDD to another machine, share my public key with that machine and with some small changes to this script have also wireless backups - rsync supports copying data to a remote server through the SSH protocol.

Have fun ;)