Go for it!

はてブロドメインで仮運用中。

メールサーバでプログラム起動する際の作法

SMTPサーバ(postfixやqmail)で受信したメールをパイプ経由でプログラムに引き渡して実行するケースは多くあると思うのですが、メールサーバが正しく処理をするための作法について。

aliasesあるいは.forwardに含まれた転送先が|(パイプ)で始まる場合、MTAは|(パイプ)以降をパスと見なしてプログラムを起動します。次の例ではmailforward宛にメールが届くと/usr/local/bin/mailforward.pyが起動する。

# grep mailforward /etc/aliases
mailforward:    | /usr/local/bin/mailforward.py

起動されたプログラムは適切な終了コードを返す必要があり、正常な場合には0、異常な場合には0以外を返す必要がある。

[code lang=“python”]

!/usr/bin/python

import sys

try: # 何かしらの処理を書く

except Exception, e: # エラーメッセージを出力する sys.stderr.write(str(e))

# 異常終了を返す。0だと正常終了だと見なされる。 sys.exit(1) [/code]

MTAは起動したプログラムの終了コードにより振るまいが異なり、具体的には、異常終了するとメールサーバはバウンスを返し、正常終了するとバウンスを返さない。

※SMTPエラーになる方法なかったっけ? ※postfix 2.3で試すとキューに入ってしまい、あとからバウンスが返ってくる…

異常終了時、プログラムは標準出力、標準エラー出力にエラーメッセージを出力することできる。内容はなんでもOKで、出力されたメッセージはログファイル、バウンスメールに記載される。ただし、ユーザにバウンスが返るのでスタックトレースなどは出力しない方がよいと思う。

で、何が言いたいのかを箇条書きでまとめると…

  • メールサーバは起動したプログラムの終了コードを判別する
  • プログラムの終了コードにより、バウンスを返すかどうか判断する
  • エラーハンドルをきちんとトラップする(エラー処理をする、例外を補足する)
  • エラー時はエラーメッセージを出力する
  • 正しい終了コードを返す(正常時=0, 異常時=0以外)

ということでした。

[ad#text_wide]