コマンドラインからメールを送信する方法

CentOS 7 で追加パッケージをインストールせずに `sendmail` コマンドでコマンドラインから日本語のメールを簡易的に送信する方法。

コマンドラインからメールを送信する方法を検索すると `mailx` パッケージをインストールして `mail` コマンドでメール送信する方法が検索上位に来るが、デフォルトでインストールされている `postfix` パッケージに同梱されている Sendmail 互換インターフェースの `sendmail` コマンドを用いれば [mailx](https://en.wikipedia.org/wiki/Mailx) をわざわざインストールする必要はない。

## メール送信コマンド例
```bash
cat << _EOM_ | sendmail -t
From: =?UTF-8?B?$(echo '送信者名' | base64)?= <from@example.jp>
To: =?UTF-8?B?$(echo '受信者名' | base64)?= <to@example.jp>
Subject: =?UTF-8?B?$(echo '件名' | base64)?=

本文1行目
本文2行目
本文3行目
_EOM_
```
https://fumiyas.github.io/2014/12/13/sendmail.postfix-advent-calendar.html
https://qiita.com/richmikan@github/items/0aea653765e485e16945
https://sendgrid.kke.co.jp/blog/?p=10958

## コマンド解説
### sendmail
ここで使用する `sendmail` コマンドは Postfix の Sendmail 互換インターフェースで、デフォルトでインストールされている `postfix` パッケージに含まれる。 [^postfix-sendmail]

[^postfix-sendmail]: "Postfix sendmail(1) コマンドは Postfix に Sendmail 互換インターフェースを提供します。" - [Postfix manual - sendmail(1)](http://www.postfix-jp.info/trans-2.3/jhtml/sendmail.1.html)

http://www.postfix-jp.info/trans-2.3/jhtml/sendmail.1.html
http://www.postfix.org/sendmail.1.html

#### `-t` オプション
`-t` オプションはメッセージヘッダーから受信者を抽出することを指定する。抽出された受信者はコマンドラインで明示的に指定された受信者に追加される。 [^sendmail-t]

[^sendmail-t]: "-t     メッセージヘッダから受信者を抽出します。これらはコマンドラインで指定された受信者に付け加えられます。" - [Postfix manual - sendmail(1)](http://www.postfix-jp.info/trans-2.3/jhtml/sendmail.1.html)

メッセージヘッダーに `To:` を指定してあれば `sendmail` コマンドの引数で受信者を明示的に指定しなくても送信される模様。

### base64
`base64` コマンドはデータを [RFC 4648](http://www5d.biglobe.ne.jp/stssk/rfc/rfc4648j.html) で定義された Base64 アルファベットにエンコード、デコードする。 [^base64]

[^base64]: "ファイルまたは標準入力を Base64 エンコード/デコードして標準出力に出力します。" - [Man page of BASE64](https://linuxjm.osdn.jp/html/GNU_coreutils/man1/base64.1.html)

### コマンド置換
**コマンド置換 (command substitution)** を使用すると、コマンドの出力でコマンド名を置き換えることができる。コマンド置換には次の2つの形式がある。 [^command-substitution]

`$(コマンド)` または `` `コマンド` `` 

[^command-substitution]: "コマンド置換 (command substitution) を用いると、 コマンド名をコマンドの出力で置き換えられます。" - [コマンド置換 - 展開 - Man page of BASH](https://linuxjm.osdn.jp/html/GNU_bash/man1/bash.1.html#lbBC)

### ヒアドキュメント
このタイプのリダイレクトは、（末尾ブランクなしで）区切り文字のみを含む行が表示されるまで、現在のソースから入力を読み取るようにシェルに指示する。
その時点までに読み取られたすべての行がコマンドの標準入力として使用される。 [^here-documents]
ヒアドキュメント (here documents) の形式は次の通り。

```
<<[-]word
     here-document
delimiter
```

[^here-documents]: "この形式のリダイレクトを用いると、 シェルは現在のソースから入力を読み込みます。 この読み込みは *word* を単独で含む行 (末尾にブランク文字があってはいけません) が現われるまで続きます。 その行までに読み込んだ行は、 コマンドの標準入力として扱われます。" - [ヒアドキュメント(Here Documents) - リダイレクト - Man page of BASH](https://linuxjm.osdn.jp/html/GNU_bash/man1/bash.1.html#lbBO)

## メールヘッダー解説
メールの仕様は [RFC 6854](https://www.rfc-editor.org/info/rfc6854) や [RFC 5322](https://www.rfc-editor.org/info/rfc5322) で規定されている。

### From: フィールド
`From:` フィールドは発信元 (Originator) フィールドの一部で、他に `Sender:` フィールドとオプションの `Reply-to:` フィールドがある。

送信元(from)フィールドは、フィールド名 "From" と、1つ以上のアドレスのカンマ区切りリスト（メールボックスまたはグループ構文）で構成される。

送信元(from)フィールドに複数のメールボックス（グループに含まれるすべてのメールボックスを含む）が含まれる場合、フィールド名 "Sender" と単一のアドレスを含む送信者(sender)フィールドがメッセージになければならない。

送信元(from)フィールドと送信者(sender)フィールドはグループ構文を使用すべきではなく、送信元(from)フィールドはメールボックスリスト構文のみを使用すべきであり、送信者(sender)フィールドはメールボックス構文のみを使用すべきである。（RFC 6854 のセクション3を参照）

送信者(sender)フィールドがグループ構文を使用する場合、グループには複数のメールボックスを含めることはできない。

いずれの場合も、フィールド名 "Reply-To" と1つ以上のアドレスのカンマ区切りリストのあるオプションの返信先(reply-to)フィールドを含めることができる。 [^from]

[^from]: [2.1.  Replacement of RFC 5322, Section 3.6.2. Originator Fields - 2.  Allowing Group Syntax in "From:" and "Sender:" - RFC 6854: Update to Internet Message Format to Allow Group Syntax in the "From:" and "Sender:" Header Fields](https://www.rfc-editor.org/rfc/rfc6854.html#section-2.1)

### To:
コマンドラインで `sendmail` コマンドの引数で受信者を明示的に指定しても、メールヘッダーの `To:` で受信者を指定しないと `undisclosed-recipients:;` が追記される。

### Subject:
`Subejct:` フィールドは情報 (Informational) フィールドの一部。他に `Comments:` フィールドや `Keywords:` フィールドがある。

`Subejct:` フィールドと `Comments:` フィールドは非構造化 (Unstructured) フィールドであり、テキストまたは折り返された空白文字を含むことができる。

[^subject]: [3.6.5. 情報フィールド - 3.6. フィールド定義 - 3. 文法 -  RFC5322(Internet Message Format)](http://srgia.com/docs/rfc5322j.html#p3.6.5)