ダミーのsendmail

Raspberry Piを利用してwebサーバを構築してみた。
WordPressやCGIなど入れてみて動作確認したりしている。

WordPressは練習用やプラグインの事前確認用にも使っているのでなかなか便利。
以前はファイルサーバのおまけ機能を使って動作確認していたが、下手をするとファイルサーバよりすらすら動いている。
普通のサーバに比べたらまだまだだけど、動作確認用には十分に働いてくれている。

のだが、一つ気になることがある。

WordPressやCGIなどからメールを送る動作を確認したいが、sendmailやPostfixをインストールしていないので、メールを送信する動作の確認ができない。
sendmailやPostfixをインストールして設定してもいいけど、内部でしか利用しない上に動作確認のためだけでそれらをインストールするのは大げさだし、sSMTPを入れて外部にメールサーバを準備するにしても、外部と通信させてメーラーで受信というのもなんか違う。

内部だけで完結できるような仕組みがあればなとググってみたけど、いいものが見つからない。
Perlで標準入力したものをファイルに出力するものが一つ見つかったけど、簡単な内容だったので、それならシェルスクリプトで自分で作ってみようかと思った。

  • dummysendmail.sh
#!/bin/sh

# メモ
# 変数の意味
#  特殊な変数
#   $0 実行ファイル名
#   $* 全引数
#   $$ PID
#   $? 最後に実行したコマンドの終了コード
#  シェル内で使用
#   $ymdhms 日時
#   $line   readの入力
#   $flag   オプションチェック用
#   $smopti -iオプションチェック

# スクリプト動作用変数(必要に応じて編集)
basedir="/hoge"
outdir="dummymail"

ymdhms=`date +"%Y%m%d%H%M%S"`

outfile="$basedir/$outdir/$ymdhms-$$.txt"

# 実行ユーザ名
exeuser=`id -nu`

#スクリプト始まり
{
    # 情報表示
    echo "X-dummysendmail-date: $ymdhms"
    echo "X-dummysendmail-cmd: $0 $*"
    echo "X-dummysendmail-pid: $$"
    echo "X-dummysendmail-user: $exeuser"
    echo "X-dummysendmail-file: $outfile"

    # -iオプションの有無チェック
    smopti=0
    while getopts ":i" flag; do
        case $flag in
            i)
               echo "X-dummysendmail-opt: -i"
               smopti=1
               ;;
        esac
    done

    # パイプかどうかの表示
    if [ -p /dev/stdin ] ; then
        echo "X-dummysendmail-input: pipe"
    else
        echo "X-dummysendmail-input: direct"
    fi

    # readコマンドで標準入力から読み込む
    # IFS=で先頭末尾の空白を削除しない
    #  -rオプションでバックスラッシュを無視させる
    while IFS= read -r line
    do
        echo "$line"

        # -iオプションがついてないときは「.」で終了させる
        # sendmailに渡された内容を確認できるようにechoは先にして「.」だけの行も表示
        if [ "$smopti" = 0 ] ; then
            if [ "$line" = "." ] ; then
                break
            fi
        fi
    done

} > $outfile
# 実行結果をまとめてリダイレクトしてファイルに書き込み

sendmailっぽく動くように「.」だけの行で終了させたり-iオプションだけは認識できるように作った。

これを適当なディレクトリにおいてln -sコマンドで/usr/sbin/sendmailを作る。
メール受信用のディレクトリは、誰でも書き込めるようにパーミッションを変えておく。

これでsendmailが実行されると、以下のようなファイルが受信用ディレクトリに保存される。

X-dummysendmail-date: 20151028222937
X-dummysendmail-cmd: /usr/sbin/sendmail -t -i
X-dummysendmail-pid: 20512
X-dummysendmail-user: www-data
X-dummysendmail-file: /hoge/dummymail/20151028222937-20512.txt
X-dummysendmail-opt: -i
X-dummysendmail-input: pipe
To: hoge@hoge.hoge
Subject: =?ISO-2022-JP?B?W3Rlc3QgYmxvZ10gGyRCJTMlYSVzJUgbKEI6ICJkdW1teXNlbmRtYWlsIg==?=
X-PHP-Originating-Script: 33:class-phpmailer.php
Date: Wed, 28 Oct 2015 13:29:37 +0000
From: hoge <wordpress@xxx.xxx.xxx.xxx>
Message-ID: <4c02a3b0d7eeecdf9a4f005c14c478f9@xxx.xxx.xxx.xxx>
X-Priority: 3
X-Mailer: PHPMailer 5.2.10 (https: //github.com/PHPMailer/PHPMailer/)
Reply-To: "hoge@hoge.hoge" <hoge@hoge.hoge>
MIME-Version: 1.0
Content-Type: text/plain; charset=ISO-2022-JP

投稿 "dummysendmail" に新しいコメントがありました
投稿者: hoge (IP: xxx.xxx.xxx.xxx, xxx.xxx.xxx.xxx)
メールアドレス: hoge@hoge.hoge
URL: 
コメント: 
dummymailのreadコマンドに-rオプション追加して、WP Multibyte Patchプラグインを有効化した

この投稿へのすべてのコメントはこちらです:
http: //xxx.xxx.xxx.xxx/hogeblog/?p=161#comments

パーマリンク: http: //xxx.xxx.xxx.xxx/hogeblog/?p=161#comment-12
ゴミ箱に移動する: http: //xxx.xxx.xxx.xxx/hogeblog/wp-admin/comment.php?action=trash&c=12
スパムとしてマークする: http: //xxx.xxx.xxx.xxx/hogeblog/wp-admin/comment.php?action=spam&c=12

これはWordPressのコメント通知を受け取った例。
X-dummysendmailで始まるフィールドはdummysendmail.shが動作した時の情報を付与して、それ以降は標準入力で受け取ったデータをそのまま張り付けているだけ。
IPアドレスやメールアドレスは加工して、勝手にリンクが張られるのでhttp:の後にスペース入れているけどこんな感じでファイルに保存されます。

ファイル名にPIDまで入れているのは、まずありえないと思うけど、同時起動で秒まで一致した時にファイル名が競合しないようにするため。

2行目のX-dummysendmail-cmdフィールドは、sendmailコマンド実行時のオプションが何か記録するため。
X-dummysendmail-optフィールドは-iオプションがついていることを確認するためだけのもの。
X-dummysendmail-inputは標準入力についていろいろ試していた時の名残りで特に意味はなし。

簡単なスクリプトだけど、これでsendmailやPostfixをインストールして設定したり、外部にメールサーバを準備したりせずに実行したらすぐファイルで確認することができるようになった。
一応dummysendmail.shが付与する情報もヘッダのフィールのていをとっているので、PCに保存して拡張子をemlに変更すればメーラーで確認することもできるはず。

保存したメールもブラウザで確認できるようにできれば一番だけど、そうするとPerlで組まないとダメだろうし、そこまで作る気力も無いなぁ・・・

ちなみに、ググりながら標準入力を表示させるという下のような簡単なスクリプトを作って試して、そこからいろいろ付け足しながら作っていった。

#!/bin/sh
if [ -p /dev/stdin ] ; then
    echo "input : pipe"
else
    echo "input : direct"
fi

while read line
do
    echo "$line"
done
カテゴリー: Linux, RaspberryPi パーマリンク

ダミーのsendmail への1件のフィードバック

  1. ぎぅ のコメント:

    dummysendmail.shスクリプト使わせて頂きました。ありがとうございます:-)

ぎぅ へ返信する コメントをキャンセル

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

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください