bashでちょっとメール送信したい時ってありますよね〜
CentOS・bashの環境でシェルスクリプトからメール送信する際、件名や本文が文字化けしまくり、発狂した挙句に結局rubyやpythonでメール送信処理を書いた経験があります。
やっぱりシェルスクリプトだけでメール送信したいので、ちゃんと調べて実装してみました。
#!/bin/sh send_mail() { from=$1 to=$2 inputEncoding="utf-8" outputEncoding="iso-2022-jp" subjectHead="=?${outputEncoding}?B?" subjectBody="`echo "$3" | iconv -f ${inputEncoding} -t ${outputEncoding} | base64 | tr -d '\n'`" subjectTail="?=" subject=${subjectHead}${subjectBody}${subjectTail} contents="`echo -e $4 | iconv -f ${inputEncoding} -t ${outputEncoding}`" echo "$contents" | mail -s "$subject" "$to" -- -f "$from" return $? } from="from@from.com" to="to@to.com" subject="件名です" contents="あああ\n いいい\n ううう" send_mail "$from" "$to" "$subject" "$contents" if [ $? -eq 1 ]; then echo "send mail failure" exit 1 fi echo "send mail success"
subjectが化ける事が多いのですが、理由はメーラーがヘッダのエンコーディングを正しく解析できていないからです。
メールのヘッダはRFCによると、=?「文字コード」?「B」?「BASE64エンコード文字列」?= となっています。
はてな区切りでイコールで先頭と末尾を囲み、B、Base64でエンコーディングしたsubjectを設定する事で、メーラーは正しくsubjectを認識できます。
本文の改行については、echoの-eオプションでエスケープの解釈を有効にすると改行されます。
1箇所ハマったところがあります。それは、CentOSのbase64コマンドは文字数が多いと勝手に改行が入る点です。手元のmacでは改行が入りませんでした。
改行のせいでヘッダが壊れ、subjectが文字化けしました。subjectBodyで tr しているのは、その改行を除去するためです。
なお、iconvはそんな優秀じゃないので、半角カタカナ等を入れると正常に処理できないかもしれません。