UNIX/Linuxの部屋 procmailコマンドの使い方

TOP UNIX/Linuxの部屋 UNIX/Linuxコマンド一覧 用語集 新版 由来/読み方辞書 環境変数マニュアル Cシェル変数 システム設定ファイル システムコール・ライブラリ ネットワークプログラミングの基礎知識 クラウドサービス徹底比較・徹底解説




コマンド procmail メール自動処理プログラム このエントリーをはてなブックマークに追加

特定の宛先、特定のサブジェクト、特定の内容などに応じて自動的にメールを処理させることができる。まず ~/.forward に
"|exec /usr/local/bin/procmail"
などと procmail のフルパスを記述しておく。必ず両端を "" で囲むこと。これでメールが届くと procmail が自動的に起動されるようになる (一部の Linux では~/.procmailrc が存在すると、メール到着時に勝手に procmail が起動されるように /etc/sendmail.cf が設定されているようだ)。

次に ~/.procmailrc に
LOGFILE=$HOME/procmail.log
:0
* ^From:.*hoge
! foo@bar.com
と書いておく (このファイルをレシピと言う)。これでメールの From フィールドに「hoge」という文字列が含まれるメールは、自動的に foo@bar.com に転送される。条件にマッチしないメールは通常通りメールスプール (/var/mail/$USER や /var/spool/mail/$USER など) に追加される。

もし希望通り動作しなかった場合は、レシピの LOGFILE で指定した ~/procmail.log を見よう。エラーになった原因などが書かれているはずである。もし何も書かれていなかったら、~/.forward の記述を見直すこと。また、ログファイルを見ても原因がわからない場合は
VERBOSE=on
LOGFILE=$HOME/procmail.log
とすることでより詳細な情報がログファイルに記録される。

レシピには上記のように
:0 [フラグ] [:ロックファイル]
* 条件
動作
という書式を連続して書くことで、複雑な動作をさせることができる ([] 内は省略可能)。以下に少し突っ込んだ使い方を示す。

サブジェクトに「hoge」を含むメールを command の標準入力に渡す。
:0
* ^Subject:.*hoge
| command
サブジェクトが(「hoge」を含む場合でなく)「hoge」であった場合だけ動作させたいなら、
:0
* ^Subject: hoge$
| command
とすればよい。また、メールが連続して届いたときに command が同時に起動されては困るなら、
:0 :
* ^Subject: hoge$
| command
と「:0」の後に「:」を付けることで、procmail に排他処理 (ロック処理) を行うよう指示することができる。この場合は「:」の後にロックファイル名を省略したので、procmail が勝手にロックファイル名を決めてくれる。

メールをリファイルすることもできる。メールスプールのような1つのファイルに複数のメールを格納する mbox 形式と、MH や Mew のような1つのメールにつき1つのファイルを使う MH 形式を選択できる。

mbox 形式は、レシピを
MAILDIR=$HOME/Mail
:0 :
* ^Subject: \[FreeBSD\-users\-jp \d+\]
FreeBSD-users-jp
とすることで、Subject が [FreeBSD-users-jp \d+] にマッチしたメールが
$HOME/Mail/FreeBSD-users-jp
というファイルにどんどん追加されていく (存在しなければ新規作成される)。

一方、MH 形式は
MAILDIR=$HOME/Mail
:0 :
* ^X-Sequence: FreeBSD\-users\-jp \d+
FreeBSD-users-jp/.
と最後に「/.」を付けることで、$HOME/Mail/FreeBSD-users-jp という *ディレクトリ* の下にメールが保存される。メールの番号は届いた順に1番から付けられ、
  • $HOME/Mail/FreeBSD-users-jp/1
  • $HOME/Mail/FreeBSD-users-jp/2
  • $HOME/Mail/FreeBSD-users-jp/3
と順に作成されていく。なお、メーリングリストの配送メールを振り分ける場合は、上記のように Subject によって振り分けるのではなく、X-Sequence や X-Ml-Name ヘッダを参照することをお勧めする。

ここで転送しつつリファイルするレシピを書いてみよう。
MAILDIR=$HOME/Mail
:0
* ^Subject: .*hoge
{
:0 c
! foo@bar.com

:0
hoge
}
このように { } で囲むことでブロックを作成することができる。2番目と3番目には「*」で始まる条件文が書いていないので、常に実行されることになる。「:0 c」の「c」は、
その条件に適合した場合、メールのコピーを作成し、以後のレシピに渡す
という意味のフラグである。

次に、1番目の条件にマッチしたものだけ特定のメールアドレスに転送し、マッチしなかったものだけ別のメールアドレスに転送する例をあげる。
:0
* ^Subject: .*hoge
! foo@bar.com

:0 E
! fuga@bar.com
Eフラグは「前のレシピにマッチしなかった場合」、つまり「ELSE IF」という意味を持つので、Subjectに「hoge」を含むメールは foo@bar.com に転送されて、そうでないメールは fuga@bar.com に転送されることになる。ただし、1番目の条件にマッチしたものは、特に定義しない限りその次の条件にはマッチしないので、上記レシピは
:0
* ^Subject: .*hoge
! foo@bar.com

:0
! fuga@bar.com
と等価である。

~/.procmailrc のパーミッションは 644 か 600 にしておくこと。664 だと、procmail が「セキュリティが甘い」と判断して、エラーとなる環境もある。その場合は /var/log/maillog など sendmail のログにエラーメッセージが吐かれる。
(参考: UNIX MAGAZINE 1998年10月号 P.36 「UNIX知恵袋42」 島 慶一)