連載
» 2004年11月16日 20時09分 公開

メールを毎日バックアップするdev Linux シェルスクリプト集

ディレクトリ名を取得してバックアップを行う手段を紹介。例として、日々のメールをサーバ上で自動バックアップするスクリプトを挙げる。

[佐藤大輔,ITmedia]

#!/bin/sh
MAILDIR=$HOME/Maildir
BACKUPDIR=$HOME/data/mail-backup
FOLDERS=".densuke .News"
AGE="+7" # 7days

cd $MAILDIR
for F in $FOLDERS; do
NAME=$BACKUPDIR/`date "+backup-INBOX$F-%Y%m%d.tar.gz"`
FILES="`find $F/cur/ -mtime $AGE`"
tar cvzf $NAME $FILES && rm -f $FILES
done

このスクリプトの動き

  • 1行目:#!/bin/sh

 実行するシェルの指定。

  • 2〜5行目:

 カスタマイズ可能な変数をリストアップしている。ここで使っている変数は、次の通りだ。

MAILDIR …… メールの置かれているディレクトリ

BACKUPDIR …… バックアップしたアーカイブを置くディレクトリ

FOLDERS …… バックアップ対象となるフォルダ名(courier-imap)

AGE …… 何日前以降のメールをバックアップするか

  • 7行目:cd $MAILDIR

 バックアップしたいメールが保存されているディレクトリへ移動する。

  • 8行目、12行目:for F in $FOLDERS; do 〜 done

 繰り返しの開始.FOLDERS変数に含まれたディレクトリがそれぞれ変数Fに渡され、ブロック内を実行していくことになる。

  • 9行目:NAME=$BACKUPDIR/`date "+backup-INBOX$F-%Y%m%d.tar.gz"`

 バックアップ先となるアーカイブ名を作成している。変数Fはfor文により、その時のフォルダ名が渡されている。また、dateコマンドはシェルエスケープで囲われているため、2004年11月8日、F=".densuke"という条件であれば、

$BACKUPDIR/backup-INBOX.densuke-20041108.tar.gz

となる。

  • 10行目:FILES="`find $F/cur/ -mtime $AGE`"

 バックアップ対象となるファイルの検出を行っている。Maildir形式であれば、新規でないメールは各フォルダ内の"cur"ディレクトリにおさめられている。その中で更新時間がAGE日以上前の物をピックアップしている。

  • 11行目:tar cvzf $NAME $FILES && rm -f $FILES

 ここまでで作成されたバックアップ先のファイル名とファイル一覧を渡してのバックアップ開始。完了した時点でファイル一覧に含まれるテンポラリファイルを削除する。

設置場所

 このスクリプトは、個人のメールのバックアップのために使うため、システムワイドで使うよりは個人用のプログラム用の場所に置くのが望ましい。一般的には、ホームディレクトリ(~)にbinディレクトリを作成し、そこに配置、パスを通すという手段が多いだろう。

1. ディレクトリ ~/bin を作成

$ mkdir ~/bin

2. スクリプトを ~/bin に配置、実行属性をつける

$ cp mail-backup ~/bin/
$ chmod +x ~/bin/mail-backup

3. 必要があれば、~/binへのパスを追加しておく、~/.bashrc(もしくは~/.bash_profile)の末尾に

PATH=$HOME/bin:$PATH

を追加し、再度ログインすればよい

動作環境〜動かすまでの手順

 このスクリプトはLinuxで一般的に使われている/bin/shで利用可能である。筆者の環境においては、

  • Debian GNU/Linux(Sarge)
  • シェルのshは、Linuxでよく行われているbashへのシンボリックリンク。bashのバージョンは2.05b.0(1)-releaseとなっている(sh --versionで確認)
  • メール環境は、postfix+procmailで配送フォルダを調整し、courier-imapでIMAPフォルダとして読み書きするようにしている。

 なお、FOLDERS変数に入れる「.densuke」や「.News」は、IMAP4のフォルダ構造をcourier-imapで管理すると作られるものであり、INBOX.densukeフォルダであれば、

~/Maildir/.densuke

が対応している。以下、変数の詳細も挙げる。

  • Maildir形式では、各ディレクトリにはcur/new/tmpのディレクトリが用意されている
  • new は新規メールが置かれる
  • cur は新規でなくなったメールが置かれる(未読でも新規でなければこちら)
  • tmp は受信したメールをnewに入れる時などに使う作業用。

 バックアップはcur内のみを対象としておけばよいだろう。

カスタマイズのポイント

 実際に使う前に、バックアップすべきフォルダをFOLDERS変数に格納させる必要がある。先に挙げたように、IMAP4におけるフォルダ名を実際のディレクトリに変換しておかなければならない。

INBOX → . (これは特殊)

INBOX.foo → .foo

INBOX.foo.bar → .foo.bar (階層構造がディレクトリになっているわけではない)

 先に挙げたスクリプト内では、IMAPフォルダの"INBOX.densuke"と"INBOX.News"がバックアップ対象となっていることになる。

 バックアップ先(BACKUPDIR変数)のディレクトリが存在することを確認し(存在しなければ作成すること)、スクリプトを実行することで7日以上前のメールがバックアップディレクトリにそれぞれ作成されるようになる。

 動作を確認し、今後自動的に行わせたいのであればcrontabエントリに次のような指定を行えばよい。

0 4 * * * /home/foo/bin/mail-backup > /dev/null

 上記の例は、毎朝4時の実行となる。

カスタマイズのポイント〜ステップアップ

 今回のスクリプトはIMAP4およびMaildir形式に依存した構造となっている(mbox形式の場合は、古いメールの抜き出しが大変なことだろう)。

 しかし、似た形式として昔から使われているMH形式フォルダであれば、このスクリプトを少々変更するだけで利用可能になるはずである。IMAP4でなくMHでローカルに持っているという人は挑戦してみることをおすすめしたいが、失敗して重要なメール消えないようにするべきである。

 この場合には、11行目を次のように指定すればよい。

tar cvzf $NAME $FILES && rm -f $FILES
から、
tar cvzf $NAME $FILES

へ変更する。この変更でさしあたり消えることはないため、防御策を講じてから試してほしい。

Copyright © ITmedia, Inc. All Rights Reserved.

注目のテーマ