mk-mode BLOG

このブログは自作の自宅サーバに構築した Debian GNU/Linux で運用しています。
PC・サーバ構築等の話題を中心に公開しております。(クローンサイト: GitHub Pages

ブログ開設日2009-01-05
サーバ連続稼働時間
Reading...
Page View 合計
Reading...
今日
Reading...
昨日
Reading...

Bash - バックアップスクリプト(年月日別ディレクトリ)!

[ サーバ構築 ] [ Linux, シェル ]

こんばんは。

年別・月別・日別にディレクトリがあり、日別ディレクトリ内に多数のファイルが保存されているとした場合に、日単位や月単位でファイルを圧縮保存したいことがあると思います。(当方はあります)

以下、当方が使用しているシェルスクリプトの紹介です。

0. 前提知識

  • GNU bash 4.1.2 での作業を想定。
  • CentOS 6.5, Linux Mint 14 で動作を確認。

1. バックアップ仕様

バックアップ元は下図のように年別・月別・日別ディレクトリに該当日のファイルが保存されているものとする。
年は半角数字4文字、月・日は半角数字2文字であるものとするが、ファイル名は任意でよい。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
path
   +-- to
   |   +-- src
   |   |   +-- 2013
   |   |   |   +-- 11
   |   |   |   |   +-- 01
   |   |   |   |   |   +-- aaaaaaaa.txt
   |   |   |   |   |   +-- bbbbbbbb.txt
   |   |   |   |   |          :
   |   |   |   |   |   :
   |   |   |   |   +-- 30
   |   |   |   |   |   +-- cccccccc.txt
   |   |   |   |   |   +-- dddddddd.txt
   |   |   |   |   |          :
   |   |   |   +-- 12
   |   |   |   |   +-- 01
   |   |   |   |   |   +-- eeeeeeee.txt
   |   |   |   |   |   +-- ffffffff.txt
   |   |   |   |   |          :
   |   |   |   |   |   :
   |   |   |   |   +-- 31
   |   |   |   |   |   +-- gggggggg.txt
   |   |   |   |   |   +-- hhhhhhhh.txt
   |   |   |   |   |          :
   |   |   +-- 2014
   |   |   |   +-- 01
   |   |   |   |   +-- 01
   |   |   |   |   |   +-- iiiiiiii.txt
   |   |   |   |   |   +-- jjjjjjjj.txt
   |   |   |   |   |          :
   |   |   |   |   |   :
   |   |   |   |   +-- 31
   |   |   |   |   |   +-- kkkkkkkk.txt
   |   |   |   |   |   +-- llllllll.txt
   |   |   |   |   |          :
   :   :   :   :   :      :

そして、バックアップ先は下図のように年別・月別ディレクトリに日別に圧縮したアーカイブファイルを保存するものとする。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
path
 +-- to
 |   +-- bak
 |   |   +-- 2013
 |   |   |   +-- 11
 |   |   |   |   +-- 20131101.tar.gz
 |   |   |   |          :
 |   |   |   |   +-- 20131130.tar.gz
 |   |   |   +-- 12
 |   |   |   |   +-- 20131201.tar.gz
 |   |   |   |          :
 |   |   |   |   +-- 20131231.tar.gz
 |   |   +-- 2014
 |   |   |   +-- 01
 |   |   |   |   +-- 20140101.tar.gz
 |   |   |   |          :
 |   |   |   |   +-- 20140131.tar.gz
 :   :   :   :   :      :

そして、バックアップ実行は、1日1回前日以前のディレクトリに対して、未バックアップの日に対してのみ行う。

2. バックアップスクリプト

仕様通りにバックアップするために以下のように Bash スクリプトを作成した。

backup_daily.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#! /bin/bash

# バックアップ元・バックアップ先
SRC_DIR_TOP="/path/to/src"
DST_DIR_TOP="/path/to/bak"

# 今日
TODAY=`date +%Y%m%d`

# バックアップ元の日付別ディレクトリ毎に処理
cd $SRC_DIR_TOP
for DIR in `ls -df */*`
do
    # 保存先ディレクトリパス設定
    if [[ "$DIR" =~ ^([0-9]{4})\/([0-9]{2})$ ]] ; then
        YEAR=${BASH_REMATCH[1]}
        MONTH=${BASH_REMATCH[2]}
    fi
    DST_DIR="$DST_DIR_TOP/$YEAR$MONTH"

    # 保存先ディレクトリが存在しなければ作成
    if [ ! -e $DST_DIR ]; then
        mkdir $DST_DIR
    fi

    # 日別ディレクトリ毎に処理
    for DIR_D in `ls -df $YEAR/$MONTH/*/`
    do
        # 保存ファイル名設定
        if [[ "$DIR_D" =~ \/([0-9]{2})\/$ ]] ; then
            DAY=${BASH_REMATCH[1]}
        fi
        DST_FILE="$YEAR$MONTH$DAY.tar.gz"

        # 今日でなく、日別アーカイブが存在しなれば、
        # アーカイブを作成して保存
        if [[ ! "$DST_FILE" =~ $TODAY ]]; then
            if [ ! -f $DST_DIR/$DST_FILE ]; then
                echo $DST_DIR/$DST_FILE
                tar zcvf $DST_DIR/$DST_FILE $DIR_D 2>&1 1>/dev/null
            fi
        fi
    done
done

色々と応用できるでしょう。

以上。

Comments