2010年12月1日水曜日

[SA-4-5] ファイル差分バックアップ(Shell Script)

内部でrcsコマンドを使用しているため,事前にrcsをインストール
#yum install rcs

backup_etc.bash
#!/bin/bash
# usage:
# 1. BACKUP_ROOT(/var/tmp/backup) に、バックアップをとりたいファイルへの
#    シンボリックリンクを張ります
#    例: cd ${BACKUP_ROOT}; ln -s /etc/nsswitch.conf
# 2. backup_etc.bash を引数なしで実行します

# バックアップ作成用ディレクトリ
BACKUP_ROOT="/var/tmp/backup"

# バックアップ作成用ディレクトリ内の最大の深さ
MAX_DEPTH=2

# RCS のチェックインメッセージ(空白/タブを入れないこと)
CHECKIN_MSG="Automatic_RCS_backup"

# 引数に応じて、
#   「ディレクトリの深さ + 1」
# を表す glob パターンを生成する
# usage: make_pattern <depth>
# ex. make_pattern 1 → "*/*"
make_pattern () {
    local -i i=$1
    local pattern="*"

    while [ $i -gt 0 ]; do
        pattern="${pattern}/*"
        let "i--"
    done

    echo "${pattern}"
}

# RCS の ci (チェックイン)コマンドを使って差分バックアップをとります
# 引数: なし
make_rcs_backup () {
    local dir
    local pattern=$(make_pattern ${MAX_DEPTH})
    local lock_user
    local file
    local msg

    # CHECKIN_MSG が設定されている場合だけ
    # msg 変数の内容を -m"メッセージ" とします
    msg=${CHECKIN_MSG:+"-m${CHECKIN_MSG}"}

    # BACKUP_ROOT に移動
    pushd "${BACKUP_ROOT}" > /dev/null

    # RCS という名前以外のディレクトリを探す
    # ※BSDシステムでは find -x . -type d ... とすること
    find . -xdev -type d \( -name RCS -prune -o -print \) | \
        while read dir; do
            case "${dir}" in
                ${pattern})
                    # MAX_DEPTH を越えたものは対象外
                    continue
                    ;;
            esac

     # 対象ディレクトリに移動
            cd "${BACKUP_ROOT}/${dir}"
     if [ ! -d RCS ]; then
  mkdir RCS
            fi

     # ファイルごとに ci を実行
            for file in *; do
  if [ -d "${file}" ]; then
      continue
  fi

  ci ${msg} -l "${file}" < /dev/null > /dev/null 2>&1
  if [ $? -ne 0 ]; then
      echo "backup FAIL: ${file}" 1>&2
  fi
     done
        done            

    # 最初いたディレクトリに戻る
    popd > /dev/null
}

make_rcs_backup

もしくは,rsyncを用いて差分バックアップを取る方法もある.
この場合,変更なきファイルはハードリンクとし,前回のバックアップから変更があったファイルのみ実際のコピーを行う為,バックアップの容量圧縮する事が可能となる.
rsync -av --delete --link-dest=../[過去] [現在]/ [保存名]

0 件のコメント: