If you want to avoid overkill of enterprise-grade Linux backup solutions just for your desktop or laptop, it’s quite easy to build a simple, OSX Time Machine -like backup system using rsync. The original idea is described in rsync Time Machine tutorial, and I’m doing exactly that for one of my desktops, with a few tweaks and simplifications.
The basic idea is to just copy the data to a new directory on each backup, while using hardlinks instead of copying already backed-up files. This makes it very easy to browse the backup history, without wasting disk space on multiple file copies:
rsync -a --link-dest=/backup/previous /data/to/backup /backup/new
I’m backing up to a (separate) local disk, but since I’m using rsync, it’s trivial to modify it to copy to a remote server. In fact, it’s better to use rsync to transfer files to a remote server than to mount network share on your computer and do local copy – network filesystems often mangle file information used by rsync to verify the files stay the same (so it can reuse them).
The OSX Time Machine does hourly, daily and weekly backups, but for the PC in question, daily backup for the last 7 days is good enough. So, for each backup I determine what’s the current date, what was the last backup name, and whether I need to delete any old backups:
todays=$(date +'%Y-%m-%d') # nicely sortable names for backups last=$(ls -r | head -1) to_delete=$(ls -r | tail -n +7) # will keep the last 6 backups cd $BACKUP_DIR rsync -aq --link-dest=$BACKUP_DIR/$last $SOURCES $BACKUP_DIR/$todays [ -z "$to_delete" ] || rm -rf $to_delete
To have daily backups, I can just put the complete script into /etc/cron.daily, which means it’ll be run early every morning, while I’m not using the computer. To make sure it doesn’t put too heavy load on the system, I can also put rsync into idle I/O class (using ionice), and give it the least priority for CPU time (using nice).
The complete script:
#!/bin/bash
# config
SOURCES="/data /home/senko"
BACKUP_DIR="/backup/mypc"
# abort if any of the commands fail
set -e
todays=$(date +'%Y-%m-%d') # nicely sortable names for backups
last=$(ls -r | head -1)
to_delete=$(ls -r | tail -n +7) # will keep the last 6 backups
cd $BACKUP_DIR
ionice -c 3 nice -n +19 rsync -aq \
--link-dest=${BACKUP_DIR}/${last} $SOURCES $BACKUP_DIR/${todays}
# now we're safe to remove the old one(s)
[ -z "$to_delete" ] || rm -rf $to_delete
One additional thing I’m considering doing in the future is putting a weekly snapshot into a compressed and encrypted archive and storing it somewhere else in case I really do need older data, and/or making the script a bit complicated to have daily/weekly/monthly backups.
Update: Many people have commented on various backup tools available for Linux. That is true, there are a lot. What this post shows is that sometimes you don’t need to install and use a special tool, if a few lines of shell script will do just fine. Most of the tools recommended have their configuration part larger than the entire script shown here. So, while reinventing the wheel is definitely not the way to go, buying a car to go to a grocery shop, instead of using a bicicle you already have is also not always optimal :-)





