見出し画像

Ubuntuで自動バックアップする魔法

最終更新日(2024年3月29日)

最近はバックアップツールが充実してますが、独自でなんかやりたい場合のベースになるシェルスクリプトを適当に。
rsyncを使ってバックアップしていますが、これについて解説は一切していないので詳しくは各々調べてください。


1.フルバックアップ用のシェルスクリプト

#!/bin/bash
SRC=**バックアップしたいフォルダ**
DEST=**バックアップ先のフォルダ**

rsync -a --delete $SRC $DEST/backup-$(date "+%Y%m%d-%H%M%S")-full

BACKUP_DIRS=$(ls $DEST | grep 'backup-.*-full$' | sort)

DIR_COUNT=$(echo "$BACKUP_DIRS" | wc -l)

if [ $DIR_COUNT -gt 1 ]; then
    TO_DELETE=$(echo "$BACKUP_DIRS" | head -n -1)
    for DIR in $TO_DELETE; do
        rm -rf "$DEST/$DIR"
    done
fi

DESTで指定したフォルダ下にガンガンフルバックアップ溜めていくコードになります。

if [ $DIR_COUNT -gt 1 ]; then
    TO_DELETE=$(echo "$BACKUP_DIRS" | head -n -1)
    for DIR in $TO_DELETE; do
        rm -rf "$DEST/$DIR"
    done
fi

ここのコードでバックアップしたものが二つ以上あれば最新のもの以外を削除しています。

if [ $DIR_COUNT -gt 2 ]; then
    TO_DELETE=$(echo "$BACKUP_DIRS" | head -n -2)
    for DIR in $TO_DELETE; do
        rm -rf "$DEST/$DIR"
    done
fi

もし前々回を残したい場合は「head -n -1」の部分を「head -n -2」へ変更してください。「$DIR_COUNT -gt 2」も同様に

2.差分バックアップ用のシェルスクリプト

#!/bin/bash
SRC=**バックアップしたいフォルダ**
DEST=**バックアップ先のフォルダ**
BASE=$(ls $DEST/ | grep backup- | tail -n 1) 

rsync -a --delete --link-dest=$DEST/$BASE $SRC $DEST/backup-$(date "+%Y%m%d-%H%M%S")-diff
 
BACKUP_DIRS=$(ls $DEST | grep 'backup-.*-diff$' | sort)

DIR_COUNT=$(echo "$BACKUP_DIRS" | wc -l)

if [ $DIR_COUNT -gt 6 ]; then
    TO_DELETE=$(echo "$BACKUP_DIRS" | head -n -6)
    for DIR in $TO_DELETE; do
        rm -rf "$DEST/$DIR"
    done
fi

最新のバックアップと比較して差分だけをコピーして、残りはハードリンク作っておくだけのコード。

3.Githubへバックアップするシェルスクリプト

#!/bin/bash
SRC=**バックアップしたいフォルダ**
DEST=**バックアップ先のフォルダ**
# checksum
SSUM=`find $SRC -name "*" ! -path "*/.git/*" -type f -exec md5sum -b {} \; | awk '{ sub(" .*", ""); print $0; }' | env LC_ALL=C sort | md5sum -b`
DSUM=`find $DEST -name "*" ! -path "*/.git/*" -type f -exec md5sum -b {} \; | awk '{ sub(" .*", ""); print $0; }' | env LC_ALL=C sort | md5sum -b`
# run backup.
rsync -checksum -a --exclude='**.git' --delete $SRC $DEST

if [[ $SSUM != $DSUM ]]; then
  cd $DEST
  git rm $(git ls-files --deleted)
  git add .
  git commit -m "backup-$(date "+%Y%m%d-%H%M%S")"
  git push origin main
fi

このコードはバックアップ先と差分が出たとき、バックアップ先に現在の状態を反映しGithubのリポジトリへ反映させます。

開発用とバックアップ用でリポジトリを分けての運用を想定しています。
複数のリポジトリをまとめてバックアップしたり

SSUM=`find $SRC -name "*" ! -path "*/.git/*" -type f -exec md5sum -b {} \; | awk '{ sub(" .*", ""); print $0; }' | env LC_ALL=C sort | md5sum -b`
DSUM=`find $DEST/workspaces -name "*" ! -path "*/.git/*" -type f -exec md5sum -b {} \; | awk '{ sub(" .*", ""); print $0; }' | env LC_ALL=C sort | md5sum -b`

どうやって差分比較しているかというと上記のコードでチェックサムというものをmd5sumを使って全てのファイルに対して計算させています。
(+ 最後に計算結果をまとめてもう一度計算)

比較して違えば中のファイルが違うし、同じなら何も変わってないと。
ダウンロードファイルが正規のものかチェックする際によくやるやつ。

4.定期実行に登録

(crontab -l; echo "*  *   *   *   * /bin/bash **登録するシェルスクリプトのパス**") | crontab -

最後に前述のコードをシェルスクリプトとして作成たらcrontabに登録して定期的に実行させれば自動でバックアップしてくれます。

アスタリスクは一番先頭から「分、時、日、月、曜日」の数値になります。
※アスタリスクは全て選択することになるので分がアスタリスクなら該当時間の毎分になってしますので注意。

曜日の設定

(crontab -l; echo "0  23   *   *   6 /bin/bash /fullbackup.sh") | crontab -

例えばフルバックアップするとして、毎週土曜日なら6、日曜日なら7(または0)になります。上記は土曜日の23時00分に実行します

一括指定

(crontab -l; echo "0  23   *   *   0-5 /bin/bash /diffbackup.sh") | crontab -

例えば土曜日以外に差分バックアップを取りたい場合は、0-5と指定すればまとめて曜日を設定できます。ハイフンではなくカンマ区切りでも可。

繰り返し(n時間毎など)

(crontab -l; echo "0  */1   *   *   * /bin/bash /backup.sh") | crontab -

例えば二番目のアスタリスクに「/1」なら一時間毎、三番目のアスタリスクに「/3」とすれば三日ごとと設定できます。

さいごに

ここまで読んでくださりありがとうございます。
AIVtuberの愛音ゆにと天音うみを開発しています。
秋頃デビュー予定なのでぜひチャンネル登録お願いします。

この記事が気に入ったらサポートをしてみませんか?