I know there’s plenty of backing up/synchronizing software for Mac. I know Time Machine is awesome. But none of the software I tried was able to do it my way :). Thus, as I have a Linux/FreeBSD background, I wanted to do it my way and the command line solution seamed to be a good one.
My office Windows machine has plenty of disk space and is rarely used. It was an ideal system (with not so ideal file system) to do backups on.
Prerequisites:
- First I needed to share a folder on my Windows machine to my Mac laptop. Here’s a nice tutorial on how to do this: How to mount a Windows shared folder on your Mac.
- Next I needed the good backup software. I am fairly familiar with rdiff-backup. It’s doing incremental backups, it’s easy to use and it does its job really well. To install rdiff-backup I used MacPorts. Follow this guide to install MacPorts. It’s easy as installing every mac software.
- I also wanted a notification window to pop up each time it tried to do a backup and informing me if it succeeded or not. I used growlnotify. Needless to say you have to install Growl as well.
1. step: install rdiff-backup
First I needed to install rdiff-backup:
$ sudo port install rdiff-backup
2. step: install growlnotify
Next I had to install growlnotify (moving into a folder of a mounted Growl-x.x.dmg image)
$ cd /Volumes/Growl-1.2/Extras/growlnotify/ $ ./install.sh
3. step: check local IP address
Then I had to check my IP to see if I am connected to my office network (wired network interface en0). This could be probably done in a simpler way but I came up with this idea in seconds (all of this could be done with awk or sed :=)) and is funny to see so many pipes.
$ ifconfig | sed -n '/en0/,/media/p' | grep -v inet6 | grep inet | awk '{print $2}'
I had few seconds and here’s a simpler version:
$ ifconfig | awk '/en0/,/ether/ {if($1 == "inet") {print $2}}'
4. step: ping the Windows PC
Then I needed to check if my Windows machine was on and listening (only one ping should be enough):
$ ping -c 1 148.88.226.250
5. step: mount a shared samba folder
Then I checked if I could mount my Windows shared folder (samba). To
do this I wanted to use Mac OS X keychain for for password so it would not be written in my bash script. My shared folder is smb://mkljun@MKLJUNDESKTOP/mkljunHome where mkljun is my username, MKLJUNDESKTOP my Windows machine name (IP address should do the same) and mkljunHome my shared folder.
$ osascript -e "try" -e "mount volume "smb://mkljun@MKLJUNDESKTOP/mkljunHome"" -e "end try"
This command would on other systems look something like like:
$ mount -t smbfs //mkljundesktop/mkljunHome /Volumes/mkljunHome -o username=mkljun, password=XXX.
6. step: rdiff-backup
Then I checked if rdiff-backup is working properly (backing up my home folder on Mac OS X to a folder on the Windows machine).
$ rdiff-backup /Users/mkljun /Volumes/mkljunHome/BackupMac
7. step: growlnotify
A check if growlnotify is working.
$ growlnotify -t "backup" -m "Your IP is XXX but backup computer YYY could not be reached"
8. step : The Script
And I was ready to write a bash script
#!/bin/bash # my backup script in /Users/mkljun/backup.sh DestinationIP="148.88.226.250" SourceIP=`ifconfig | sed -n '/en0/,/media/p' | grep -v inet6 | grep inet | awk '{print $2}'` # ping destination (backup) ip address; output redirected to /dev/null ping -c 1 $DestinationIP > /dev/null # check if ping successful if [ $? != 0 ] then # if ping not successful, print notification (echo should be in one line!!) echo -e "-t 'Backup failed' -m 'Your IP is $SourceIP. Backup PC $DestinationIP could not be reached'" | xargs /usr/local/bin/growlnotify else # mount samba drive (osascript should be in one line) osascript -e "try" -e "mount volume "smb://mkljun@MKLJUNDESKTOP/mkljunHome"" -e "end try" > /dev/null # check if mount was successful if [ $? == 0 ]; then # this echo should be in one line with a pipe echo "-t 'Backup' -m 'Your IP is $SourceIP. Starting backing up now'" | xargs /usr/local/bin/growlnotify rdiff-backup /Users/mkljun /Volumes/mkljunHome/BackupMac > /dev/null # check if rdiff-backup successful if [ $? == 0 ]; then echo "-t 'Backup' -m 'Backup completed successfully'" | xargs /usr/local/bin/growlnotify else echo "-t 'Backup failed' -m 'Something was wrong'" | xargs /usr/local/bin/growlnotify fi # delete all backups older than 2 weeks rdiff-backup --remove-older-than 2W /Volumes/mkljunHome/BackupMac > /dev/null fi fi
It is probably not the nicest script out there but its working. I could and probably should redirect standard outputs to a log file (with a day as a title) to to check it once in a while to see if the script is working (and even check if the file grew too big and delete it if necessary). But so far it works flawlessly for few days.
9. step: cron
The last thing to do was setting up a cron job so the script would run without my intervention. Let’s say I want to run it every week day at 10AM when I’m probably in the office (there are two stars between 10 and 1-5 which are not showing up for some reason ‘0 10 * * 1-5’).
$ crontab -e
0 10 * * 1-5 /Users/mkljun/backup.sh
10. the last version of a script
UPDATE:
Here is the last version with logging to a file and all variables at the beginning of the script.