LinuxでTime Machineみたいな世代バックアップを実現する

有名な方法だと思いますがメモとして書いておきます。以下のようなスクリプトを書いてcronで走らせます。

#!/bin/bash

function backup(){
  SRCDIR="$1"
  NAME=$(basename $1)
  DSTBASEDIR="$2"
  LATESTBKUP=$(ls $DSTBASEDIR | grep $NAME- | tail -n 1)


  rsync -avh --link-dest="$DSTBASEDIR/$LATESTBKUP" $SRCDIR/ "$DSTBASEDIR/$NAME-$(date +%Y%m%d-%H%M%S)/"
}

backup /path/to/source1 /path/to/backup
backup /path/to/source2 /path/to/backup

ポイントは rsync の --link-dest オプションで、

--link-dest=DIR          hardlink to files in DIR when unchanged

という動きをします。多分、こういう世代バックアップ/インクリメンタルバックアップのようなことをするためのオプションとして実装されたのだと思われます(それ以外の用途が思いつかない…)。これをすると変化していないファイルはハードリンクとしてコピーされるのでファイル容量が節約できます。不要になったファイルは何も考えずバックアップしたディレクトリごと消していけば、ハードリンクのリンク数がゼロになった段階で領域が開放されるのでこれまた都合が良いです。
古い日付のファイルは自動で消すなどのcron設定をすればこれもまた自動化できるでしょう。

Time MachineとかNASの機能で同様のことを実現しているケースと比較すると、こっちの方法だとこれは単にファイルがそのまま存在しているだけなのでバックアップ先のメディアさえ無事ならばデータ救出が容易というメリットもあると思います。

追記:

最初の一回は --link-dest オプション無しでrsyncしてください。