AIX環境でsendmailコマンドで件名を日本語で、本文を「iso-2022-jp」にエンコードしてメールを送信する

AIX環境でsendmailコマンドでメールを送信する。 - 猫にWebの続きですが、
前回のシェルでは件名に日本語を使用できません。
理由はこんな感じです。

インターネットの世界でSubjectに日本語を使用する場合には、
ISO-2022-JPで書かれた文字列をBase64エンコードした上で、
MIMEで定められた書式で記述するのが普通だからです。


http://www-01.ibm.com/support/docview.wss?uid=std3565c90ed60af169f492571a900338d47

最初はエンコードもシェルの中でしようと思い、
「iconv」コマンドを使おうと思ったのですが、
「iconv -l」で調べても「ISO-2022-JP」の文字コードがありませんでした。
そこで「perl」コマンドで実行する事にしました。

エンコードするperlスクリプト
IBMが提示しているものをそのまんま使わせてもらいました。

#!/usr/bin/perl
############################################################
# Program名称 : encode
# 処理概要    : 宛先、件名に日本語を使用する為のエンコーダー
#############################################################

use Encode;
use Encode::Guess qw( euc-jp shiftjis 7bit-jis );
use MIME::Base64 qw(encode_base64);
chomp($str=<STDIN>);
print "=?iso-2022-jp?B?";
print encode_base64(encode("7bit-jis",decode("Guess",$str)),"");
print "?=\n";

件名を日本語で表示して送信する場合はこんな感じです。
宛先も同様の実装でOKです。

SUBJECT=`echo "日本語の件名です。" | ./encode`

変換するとこんな文字列になります。

=?iso-2022-jp?B?GyRCRnxLXDhsJE43b0w+JEckORsoQg==?=

「?」で区切られた3つの要素が1つの文字列になっています。
真ん中の「B」は「base64」の「B」です。
3つ目のバラバラの文字列が変換した日本語です。


次はメールの本文を「SHIFT-JIS」から「iso-2022-jp」にエンコードします。
この理由はこんな感じです。

現在、ほとんどのMTAは8bit文字にも対応しているが、
全MTAで問題なく扱えるとは言い切れません。
異機種環境で問題なく日本語を使用するためには、
本文に使う日本語の文字コードとしてISO-2022-JPを使用してください。
ISO-2022-JPは7bitであるためほぼ全てのMTAが扱えます。


http://www-01.ibm.com/support/docview.wss?uid=std3565c90ed60af169f492571a900338d47

メールの本文は件名や宛先と違って、
複数行書かれたテキストファイルを読み込む事になります。
そこでエンコードするperlスクリプトはこんな感じです。

#!/usr/bin/perl
############################################################################
# Program名称 : bodyEncode
# 処理概要    : メール本文の文字コードを「iso-2022-jp」にするエンコーダー
############################################################################

use Encode;
use Encode::Guess qw( euc-jp shiftjis 7bit-jis );

while(<>){ print encode("iso-2022-jp",decode("Guess",$_)); }

1;

同期の友人の「perl monger」に作ってもらいました。
本当に助かりました。ありがとう。
他力本願過ぎるのは目をつむってやって下さい。


エンコード部分を改修したシェルはこんな感じになりました。

#!/bin/bash
############################################################
# Program名称 : sendmail.sh
# 処理概要    : メールを送信する
#############################################################

########## < shell start > ##########

### 宛先と件名を変換
FROM_ADDRESS=`echo "FROM ほげほげ" | ./encode`"<from_hoge@co.jp>"
TO_ADDRESS=`echo "TO ほげほげ" | ./encode`"<to_hoge@co.jp>"
SUBJECT=`echo "日本語の件名です" | ./encode`

### 文字コードを指定
echo "Mime-Version: 1.0"                              >> tmp.txt
echo "Content-Type: text/plain; charset=ISO-2022-JP"  >> tmp.txt
echo "Content-Transfer-Encoding: 7bit"                >> tmp.txt

### 宛先、件名を指定
echo "From: ${FROM_ADDRESS}"                          >> tmp.txt
echo "To: ${TO_ADDRESS}"                              >> tmp.txt
echo "Subject: ${SUBJECT}"                            >> tmp.txt
echo ""                                               >> tmp.txt

### メール本文
echo "日本語"                                         >> tmp.txt
echo "にほんご"                                       >> tmp.txt
echo "ニホンゴ"                                       >> tmp.txt

### メール送信
cat tmp.txt | perl bodyEncode | sendmail -f ${FROM_ADDRESS} -i -t
rm -f tmp.txt

本文を文字コードiso-2022-jp」で送信するには、
明示的に文字コードを指定する必要があります。
実は今回の件で初めて普段使っているメーラー(Thunderbird)で
メールのソースというものを見たのですが、
ちゃんと裏側ではエンコードされている事を知り、
ちょっと新たな発見でした。


sendmail」は奥が深い、そして「perl」は優れものだ。