This is (a variant of) the script I use (/home/pduck/bup.sh
):
#!/usr/bin/env bash
src_dir=/home/pduck
tgt_dir=/tmp/my-backups
mkdir -p $tgt_dir
# current backup directory, e.g. "2017-04-29T13:04:50";
now=$(date +%FT%H:%M:%S)
# previous backup directory
prev=$(ls $tgt_dir | grep -e '^....-..-..T..:..:..$' | tail -1);
if [ -z "$prev" ]; then
# initial backup
rsync -av --delete $src_dir $tgt_dir/$now/
else
# incremental backup
rsync -av --delete --link-dest=$tgt_dir/$prev/ $src_dir $tgt_dir/$now/
fi
exit 0;
It uses rsync
to locally copy the files from my home directory to a backup location, /tmp/my-backups
in my case.
Below that target directory a directory with the current timestamp is created, e.g. /tmp/my-backups/2018-04-29T12:49:42
and below that directory the backup of that day is placed.
When the script is run once again, then it notices that there is already a directory /tmp/my-backups/2018-04-29T12:49:42
(it picks the "latest" directory that matches the timestamp pattern). It then executes the rsync
command but this time with the --link-dest=/tmp/my-backups/2018-04-29T12:49:42/
switch to point to the previous backup.
This is the actual point of making incremental backups:
With --link-dest=…
rsync does not copy files that were unchanged compared to the files in the link-dest directory. Instead it just creates hardlinks between the current and the previous files.
When you run this script 10 times, you get 10 directories with the various timestamps and each holds a snapshot of the files at that time. You can browse the directories and restore the files you want.
Housekeeping is also very easy: Just rm -rf
the timestamp directory you don't want to keep. This will not remove older or newer or unchanged files, just remove (decrement) the hardlinks. For example, if you have three generations:
/tmp/my-backups/2018-04-29T...
/tmp/my-backups/2018-04-30T...
/tmp/my-backups/2018-05-01T...
and delete the 2nd directory, then you just loose the snapshot of that day but the files are still in either the 1st or the 3rd directory (or both).
I've put a cronjob in /etc/cron.daily
that reads:
#!/bin/sh
/usr/bin/systemd-cat -t backupscript -p info /home/pduck/bup.sh
Name that file backup
or something, chmod +x
it, but omit the .sh
suffix (it won't be run then). Due to /usr/bin/systemd-cat -t backupscript -p info
you can watch the progress via journalctl -t backupscript
.
Note that this rsync
solution requires the target directory to be on an ext4
filesystem because of the hardlinks.
rsnapshot
which is based onrsync
and intended for backups (with automatically deletion of old backups etc.)...?