/var/spool/mail/ に届いたメールを処理する方法

概要

cron で処理した結果がメールで送られてくるときに /var/spool/mail/username に届く。mbox 形式で書き込まれて、これは mailx で読んだり消したりできる。だけど、mailx は対話式のプログラムで自動で中身を見て処理したりできない。

メールの数が大量になると(例えば毎分スクリプトを回してたりすると)チェック不能になるし、かといってメールを送らないようにするのはちょっと・・・みたいな時に使えます。

procmail とかで受信時に処理するという手もあると思うけど、今回はまとめてバッチ処理する方法を探してみた。

動作環境は CentOS 7 + Python 2.7。

大雑把な手順

  1. GNU Mailutils の movemail で /var/spool/mail/username を別のディレクトリ(ホームディレクトリ)に移動
    • /var/spool/mail/ はユーザ権限で新しいファイルを作れないので、mbox ファイルを編集するときにロックが取れないという問題があるので、予めメールを移動
  2. mbox を解釈できるライブラリ等を使って mail を解釈して処理
    • 使えるツールはいろいろあると思うが今回は python を使用
    • cron から送られてくるメールに対してテストケースを書いて特定の条件(エラー等)を満たすメールだけを残す、とか特定のファイルに書き出す、とかの使い方を想定

GNU Mailutils のインストール

CentOS のリポジトリにはなさそうだったので公式サイトからダウンロードしてコンパイル・インストール。configure -> make -> make install のいつもの流れで OK。

メール処理スクリプトの例

  • $MAIL が設定されていることを前提(/var/spool/mail/username とかになっているはず)
  • $HOME/mail/INBOX をメールの移動先とした(予め $HOME/mail を作っておく)
  • GNU Mailutils のツールにはパスを通しておく
  • このままは動かないのでご注意
#!/usr/bin/env python

import os
import subprocess
import mailbox

def chkMsg(msg):
    subject = msg["subject"]
    body = msg.get_payload()

    # メッセージの内容によって返り値を変える
    if 削除:
        return 0
    else:
        return 1

mboxpath = os.environ["HOME"] + "/mail/INBOX"
subprocess.call(["movemail", os.environ["MAIL"], mboxpath])

mbox = mailbox.mbox(mboxpath)
to_remove = []
for key, msg in mbox.iteritems():
    if chkMsg(msg) == 0:
        print "Removing: ", key
        to_remove.append(key)

mbox.lock()
try:
    for key in to_remove:
        mbox.remove(key)
finally:
    mbox.flush()
    mbox.close()

subprocess.call(["mail", "-f", mboxpath])

参考

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です