Cronで日本語のメールを送ると文字化け・添付ファイルになる

2021-07-08

日本語の文字列があるメールを送ると添付ファイルなる場合の対処法

件名は日本語でメール本文に日本語文字列があるメールを送信するシェルスクリプトを作って、スクリプトを実行してメールを送信すると受信したメールの件名・本文ともメールクライアントでは、日本語で表示されますが、そのスクリプトをCronで実行すうると、メール件名は「????」と文字化けしメール本文は添付ファイルとなってしまいます。

これはCronで実行するとロケール環境変数がスクリプトで実行している環境のユーザーと異なるためになります。
シェルスクリプトで「locale」コマンドを実行するような簡単なスクリプトを作って実行してみました

$ vi test.sh
#!/bin/bash

locale > /var/tmp/locale.txt

# 作成した「test.sh」を実行してロケール環境変数をどのようになっているか確認します
$ sh  test.sh
$ cat /var/tmp/locale.txt
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

作成したシェルスクリプトを実行すると「LANG=en_US.UTF-8LC_CTYPE=ja_JP.UTF-8」となっています。

このシェルスクリプトをCronで実行すると下記のようなロケール環境変数になります

$ cat /var/tmp/locale.txt
LANG=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=

Cronで実行した場合は「LANG=LC_CTYPE="POSIX"」となり、ユーザーで実行したシェルスクリプトを実行した場合と異なり「LANG=」と空白となっており、そのため日本語文字列を含むメールが添付ファイルになったりするようです

ネットで調べるとシェルスクリプトを実行する際に「export LC_CTYPE=ja_JP.UTF-8」、「export LANG=ja_JP.UTF-8」と「export」コマンドで日本語のロケール環境変数を指定してシェルスクリプトに記載すると日本語文字列を含む場合も添付ファイルにならずにメールを送れるようです。

確認のため以下のようなシェルスクリプトを作ってCronで実行しました

#!/bin/bash

echo "日本語文字列テスト1" | mail -s "テスト1" gm.yabe@gmail.com

export  LC_CTYPE=ja_JP.UTF-8
locale > /var/tmp/locale2.txt
echo "日本語文字列テスト"2 | mail -s "テスト2" gm.yabe@gmail.com

export LANG=ja_JP.UTF-8
locale > /var/tmp/locale3.txt
echo "日本語文字列テスト3" | mail -s "テスト3" gm.yabe@gmail.com

実行するとロケール環境変数を日本語に指定している場合は、日本語文字列を含むメールは普通のメールのように日本語は文字化けせず本文も添付されることなく送信できました

また、exportコマンドでロケール環境変数を指定した際に環境変数がどのようになっているか調べると下記のようになっています

# export LC_CTYPE=ja_JP.UTF-8  と指定した場合
$ cat /var/tmp/locale2.txt
LANG=en_US.UTF-8
LC_CTYPE=ja_JP.UTF-8
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

# export LANG=ja_JP.UTF-8 と指定した場合
$ cat /var/tmp/locale3.txt
LANG=ja_JP.UTF-8
LC_CTYPE=ja_JP.UTF-8
LC_NUMERIC="ja_JP.UTF-8"
LC_TIME="ja_JP.UTF-8"
LC_COLLATE="ja_JP.UTF-8"
LC_MONETARY="ja_JP.UTF-8"
LC_MESSAGES="ja_JP.UTF-8"
LC_PAPER="ja_JP.UTF-8"
LC_NAME="ja_JP.UTF-8"
LC_ADDRESS="ja_JP.UTF-8"
LC_TELEPHONE="ja_JP.UTF-8"
LC_MEASUREMENT="ja_JP.UTF-8"
LC_IDENTIFICATION="ja_JP.UTF-8"
LC_ALL=