サーバの監視スクリプトにおいて、ログファイルを添付して通知メールを送りたい場合など、Linux のシェル スクリプトや MS-DOS のバッチ ファイルから、添付ファイル付きでメールを送信するための覚書きです。特に、SMTP サーバに直接ネットワーク接続して送信するのではなく、sendmail などの MTA を利用して送信する場合について。
bash を使った例です。multipart/mixed 形式のデータを sendmail を利用して送信します。メール本文や添付ファイルのセクション(?)を MAIL_BOUNDARY で区切って、添付ファイルは base64 を利用して binary⇒ascii 変換して挿入します。複数ファイルを添付する場合にも、MAIL_BOUNDARY で区切ってどんどん追加すれば OK。
#!/bin/bash
ATTACH_FILETYPE=image/jpeg
ATTACH_FILENAME=58bf1448.jpg
ATTACH_FILEPATH=/tmp/${ATTACH_FILENAME}
SENDMAIL=/usr/sbin/sendmail
BASE64=/usr/bin/base64
MAIL_BOUNDARY=MAIL_BOUNDARY.$RANDOM$RANDOM$RANDOM
$SENDMAIL -t << SENDMAILHEREDOC
From: This is a pen <root@lab.magicvox.net>
To: User1 <user1@example.com>,
User2 <user2@example.com>
Subject: 日本語の題名
MIME-Version: 1.0
Content-type: multipart/mixed; boundary=${MAIL_BOUNDARY}
Content-Transfer-Encoding: 7bit
--${MAIL_BOUNDARY}
Content-type: text/plain; charset=utf8
Content-Transfer-Encoding: 7bit
ここにメール本文
--${MAIL_BOUNDARY}
Content-type: ${ATTACH_FILETYPE}; name=${ATTACH_FILENAME}
Content-Disposition : attachment; filename=${ATTACH_FILENAME}
Content-Transfer-Encoding: base64
`${BASE64} ${ATTACH_FILEPATH}`
--${MAIL_BOUNDARY}--
SENDMAILHEREDOC
sendmail へのパイプを open してメールを送信するサンプル コードをよく見かけますが、これを土台に、先のシェル スクリプトと同様に multipart/mixed 形式データを自前で用意して流しこむ方法があります。ただ、ソースコードが煩雑になるので、MIME::Lite などのモジュールを利用した方が判りやすくて良いと思います。
use MIME::Lite;
use Encode;
# コンテナを作成
my $msg = MIME::Lite->new(
From => 'This is a pen <staff@daiei-g.com>',
To => 'user1@example.com, User2 <user2@example.com>',
Subject => Encode::encode( 'MIME-Header-ISO_2022_JP', "日本語の件名" ),
Type => 'multipart/mixed',
);
# メッセージ部分
$msg->attach(
Type => 'text/plain; charset="utf-8"',
Data => <<PERLHEREDOC,
ここにメッセージ本文
PERLHEREDOC
);
# 添付ファイル
$msg->attach(
Type => 'application/octet-stream',
Disposition => 'attachment',
Path => "/path/to/your/file.jpg",
Filename => 'alternative-filename.jpg',
);
# 送信
$msg->send();
multipart/mixed 形式のデータを sendmail にパイプして送信する方法メール送信用の小さなクライアント プログラムを利用します。SMAIL あたりが使いやすそうです。
smail.exe ^
-h"smtp.example.com" ^
-f"from@example.com" ^
-s"Test Mail from SMAIL" ^
-Fbody.txt ^
user1@example.com,user2@example.com