そういうのがいいブログ

SIerで働く30代サラリーマンSEがインフラエンジニアに憧れてLinux・クラウド・AWSの勉強をするブログ

Linuxでmailコマンドでファイルを本文に入れると添付ファイルになってしまう

※[PR]当ブログの記事の中にはプロモーションが含まれています。

Linuxでmailコマンドでファイルを本文に入れると、添付ファイルになってしまう事象について教えてほしい。

こういった疑問に答えます。

本記事の内容

この記事を書いている私は、某SIerに勤務しながら、
WEB系エンジニア・インフラエンジニアに憧れて、プログラミングおよびインフラ技術の勉強をしています。

こういった私が、解説していきます。

私が実機で試したコマンドや画像を載せて書いています。
記事の信頼性担保に繋がると思います。

LinuxCentOS・OracleLinux)でmailコマンドでファイルを本文に入れると添付ファイルになってしまう事象

OracleLinuxサーバでOracleデータベースの定期バックアップ(RMAN)をcronで実行しています。
定期バックアップ時のログファイルをメール本文に入れて管理者に送信しています。

①:RMANバックアップ実行

LogDir=/home/oracle/log/rmanlog/
LogFile=backup_database_$datetime.log
LogFilePath=$LogDir$LogFile
rman target / @/home/oracle/system/shl/database_backup.rman log=$LogFilePath
cat $LogFilePath | mail -s [SV-PLUTO]RMAN_BACKUP ●●●●●●●@ad.planet.jp

②:バックアップ後の不要ファイル削除

LogDir=/home/oracle/log/rmanlog/
LogFile=delete_obsolete_$datetime.log
LogFilePath=$LogDir$LogFile
rman target / @/home/oracle/system/shl/delete_obsolete.rman log=$LogFilePath
cat $LogFilePath | mail -s [SV-PLUTO]RMAN_DELETE ●●●●●●●@ad.planet.jp

①:RMANバックアップ実行結果のメール

ログファイルの内容が本文に入った状態のメールになっています。

メールヘッダーの「Content-Type」はtext/plain; charset=utf-8になっています。

②:バックアップ後の不要ファイル削除結果のメール

こちらは、本文は全く空っぽで、ログファイルは添付ファイルになったメールになっています。

メールヘッダーの「Content-Type」はapplication/octet-streamになっています。

添付ファイルを開くと、ログの内容が確認できました。

ファイルは、「UTF-8」で改行コードは「LF」になっています。

①と②の違い

  • ①: ログファイルが本文の中にそのまま入ったメール。Content-Typeはtext/plain; charset=utf-8
  • ②: ログファイルが添付ファイルになったメール。Content-Typeはapplication/octet-stream

同じように処理しているつもりなのですが、どうして①と②のような違いが起きるのか、原因を調査中です。

[2021/01/03追記]

原因が分かりました。

結論から言うと、ファイルの中に「改行コードのCRLFが入っていたため」でした。

fileコマンドでログファイルの改行コードを確認

①:メール本文の中にそのまま入る方のファイル

[oracle@SV-PLUTO rmanlog]$ file backup_database_20201227_020001.log
backup_database_20201227_020001.log: UTF-8 Unicode text

②:メールの添付ファイルになってしまう方のファイル

[oracle@SV-PLUTO rmanlog]$ file delete_obsolete_20201227_040001.log
delete_obsolete_20201227_040001.log: UTF-8 Unicode text, with CRLF, LF line terminators

両方とも、文字コードは「UTF-8」ですが、
添付ファイルになってしまう方のログファイルは、「with CRLF, LF line terminators」と表示されています。
つまり、改行コードに「CRLF」が混在してしまっています。

どこに改行コード「CRLF」が入っているか確認

cat-eオプションをつけると改行コードが制御文字で表示できます。

改行コード「LF」は、制御文字$で表示されて、
改行コード「CRLF」は、制御文字^M$で表示されるので区別ができます。

cat -e delete_obsolete_20201227_040001.log >> delete_obsolete_20201227_040001_e.log
[oracle@SV-PLUTO rmanlog]$ cat -e delete_obsolete_20201227_040001.log >> delete_obsolete_20201227_040001_e.log
[oracle@SV-PLUTO rmanlog]$ head delete_obsolete_20201227_040001_e.log
$
Recovery Manager: Release 19.0.0.0.0 - Production on M-fM-^WM-% 12M-fM-^\M-^H 27 04:00:01 2020$
Version 19.3.0.0.0$
$
Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.$
$
M-cM-^BM-?M-cM-^CM-<M-cM-^BM-2M-cM-^CM-^CM-cM-^CM-^HM-cM-^CM-;M-cM-^CM-^GM-cM-^CM-<M-cM-^BM-?M-cM-^CM-^YM-cM-^CM-<M-cM-^BM-9: ORCLCDB (DBID=2800378676)M-cM-^AM-+M-fM-^NM-%M-gM-6M-^ZM-cM-^AM-^UM-cM-^BM-^LM-cM-^AM->M-cM-^AM-^WM-cM-^AM-^_$
$
RMAN> delete obsolete;^M$ ←★★★改行コード「CRLF」
2> exit$

実行コマンドの中に、改行コード「CRLF」が入っていました。Windowsパソコンでシェルを作ってLinuxサーバにアップするときに混入してしまったようです。

対処手順

原因が分かれば対処方法は簡単で、実行コマンドを書いたシェルの改行コードを「LF」に修正するだけです。

メールの本文にログが入るようにできた

対処後のメールは下記のように、メール本文の中にログが表示されるようになりました。

Content-Typeもtext/pain; charset=utf-8になりました。