サーバのバックアップ用シェルスクリプトをmain関数を入れて書き直した

3 min read

こんにちは、無能です。
しばらく前に書いてたバックアップ作成の為のシェルスクリプトを書き直しました。

はじめに

ちょっと前に書いていたのですが、改めて見てみるとバックアップした古いtar.gzファイルを削除するコード入れてなかったりしていてちょっと長くなりそうだなーと思ってmain関数にまとめた。
めんどくさがり屋な自分にとってはとにかく短く収めることが重要なので書き直してみた。
本当は引数でバックアップ先とバックアップ元を指定できるようにすれば汎用性あるしcronに記述したときにわかりやすいのでいずれかやる。

解体

#!/bin/bash

MOUNT_DIR="/your/mount/point"

SRC_DIR="/want/to/backup/dir"
BK_DIR="backupdir"

EXCLUDE_FILE=""  # 除外ファイル指定 --exclude=your/path
W_DIR=`echo $SRC_DIR | awk -F/ '{print $(NF)}'`

# マウントポイントを確認し、マウントされていなければマウントする
check_mount() {
    df | grep "$MOUNT_DIR" > /dev/null
    if [ $? -ne 0 ]; then
        break
    else
        mount $MOUNT_DIR || exit 1
    fi
}

# 古いバックアップファイルを削除する
rm_old_backups() {
    BK_COUNT=`ls -1 $MOUNT_DIR/$BK_DIR/*.tar.gz 2>/dev/null | wc -l`
    if [ "$BK_COUNT" -ge 3 ]; then
        ls -1t $MOUNT_DIR/$BK_DIR/*.tar.gz | tail -n +4 | while read file; do
            rm -f "$file"
        done
    fi
}

# バックアップを作成する
create_backup() {
    rsync -av $EXCLUDE_FILE $SRC_DIR $MOUNT_DIR/$BK_DIR
    tar cfz $MOUNT_DIR/$BK_DIR/"$W_DIR"_`date +"%Y%m%d"`.tar.gz -C $MOUNT_DIR/$BK_DIR $W_DIR
    rm -rf $MOUNT_DIR/$BK_DIR/$W_DIR/*
}

main() {
    check_mount  # マウントを確認し、必要ならマウント
    mkdir -p $MOUNT_DIR/$BK_DIR  # バックアップディレクトリの作成
    rm_old_backups  # 古いバックアップの削除
    create_backup  # 新しいバックアップの作成
    umount $MOUNT_DIR || exit 1  # マウント解除
}

main

マウント/アンマウントすることを想定してるのでその判定を入れる必要があり、不思議なんだがmountpointコマンドでマウントされているかどうか判定できるものがありそれをやってみたらマウントされてるのにマウントされていません表示でたりで適正な戻り値が取得できなかった。
なのでふと思えば、マウントされていなければdf結果にも出てこないのでこのdfの標準出力をgrepしマウント先がgrep出来た時の戻り値で判定すれば結構間違いないかなあ…と。

元はcpコマンドでシンプルに一度コピーしてからtarで固めていたのだが"コピーの除外ファイル"を指定したくて、rsyncは使えるらしく。みんなrsync使うようになってる訳だ。

わざわざ$W_DIRを指定してる理由はrysncで使うから値を作っておく必要があった。
そしてキモなのが古いtar.gzファイルを削除判定なのだが、lsで確認するばfindで強欲にその下の階層を見に行くことが無いのでディスクI/O的にも負荷が掛りづらく安全だと感じたのでやってみた。
それでtailでファイル名を取得することで明確に何個までのファイルを許可するか決めれるし何気にいいのでは?ということです。

おわり

まあぶっちゃけmain関数に起こすほどでもなかった気はするけど結果的に見やすくなった気がするのでよしとします。
それでは。また宜しくお願いします。