Shell scriptからメールを送る †mailを送信する方法はいくつかあります。ここでは、shell scriptから sendmailコマンドを使ってメールを 作成して、送信する方法について説明します。 メールの形式 †まず、電子メールの形式についておさらいして、「どのように作成して送信すれば良いのか」という点に注目します。 電子メールは、テキスト形式であり、実際の電子メールを表示させてみると、下記のようなテキスト形式の電文になっていることがわかります。 以前は、コンソール上でほとんど生の状態で読み書きすることもありましたが、最近では、きれいに整形して表示される電子メール用 ソフトウェアを使うことが多くなりました。そのため、生でみる機会は少なくなりました。しかし、電子メールを送信する プログラムを作成するには、どのような形式になっているか知っておくことは、理解するための大きな手がかりなるので、知っている必要があります。 以下に電子メールのサンプルを示します。このようなテキスト形式になっています。 Return-Path: <ryuchi @ xxxxxxxxxxx> Received: from mailhost-xxxxx.ryuchi.??? ([IPv6:2001:????????::1]) by mailhost-yyyyyy.ryuchi.??? (8.14.4/8.14.4) with ESMTP id q6JD9N8s044050 for <ryuchi @ xxxxxxxxx>; Thu, 19 Jul 2012 02:09:23 +0900 (JST) (envelope-from ryuchi @ yyyyyyyyyyy) Received: <中略> Date: Thu, 19 Jul 2012 02:09:23 +0900 (JST) Message-Id: <201207191309.q6JD9N4t083517@xxxxxxxxxxxxxxxxx> From: ryuchi @ xxxxxxxxxx To: ryuchi @ yyyyyyyyyyyy Subject: =?ISO-2022-JP?B?GyRCJUYlOSVIJWEhPCVrGyhC?= Mime-Version: 1.0 Content-Type: text/plain; charset=iso-2022-jp Content-Transfer-Encoding: 7bit X-UIDL: AP0!!GU*#!P*L"!^6L!! これはテスト用として送信しています。 ちゃんと届くでしょうか。 ※一部を伏字にしています。 電子メールのテキストにはいくつかお約束があります。その主なお約束は下記のようなものです。 これは、決まり事になっています。
英語のテキストのみを使った電子メールであれば、特に問題ありませんが、日本語などの多国語に対応したり、 画像や、プログラムファイルなどを添付したりするには、この制約だけでは、実現することが困難です。 そこで最初の約束ごとを守りながら、いくつかの約束ごとを追加して、対応できるように改良されています。 例えば、日本語のメールを実現するためには、主に下記の約束ごとを追加します。
※注) 日本語のテキストを送信するには UTF-8を使う方法もあります。ここでは、ISO-2022-JP の場合に限定します。 UTF-8 については別の機会にでも... ここでは、日本語の文字を使うときには ISO-2022-JP という文字コードを指定する、と覚えるといいでしょう。 (JIS漢字を指定 しているのと同じです。) Base64 とか printable Quoted というのは 制御文字などの印刷不能なコードを 印刷可能文字に置き換える手順の名前です。 それぞれの形式に変換することを「エンコード」(符号化)、もとの形式に戻すことを「デコード」(復号化)と言います。 それぞれに、利点と欠点がありますので、状況に応じて使い分けるのがベストですが、日本語のテキストをエンコードするときは Base64 を使われることが多いようです。 最後の約束として、これら拡張されたメールは MIME形式のメールと呼ばれています。そして MIME形式になったことを 示すヘッダが定義されていますので、これらのヘッダを追加します。追加されているのは 3行のヘッダです。 Mime-Version: 1.0 Content-Type: text/plain; charset=iso-2022-jp Content-Transfer-Encoding: 7bit 最初の Mime-Version: は MIME形式であることと、その Version を示しています。現在は 1.0 なので、このヘッダは そのまま使います。 Content-Type: は、メールの形式を示しています。添付ファイルがある形式なのか、同じ内容を複数の形式で記述されているのか などを示しています。 text/plain というのは、従来からある テキスト形式であることを示しています。そして ボディの 言語が charset= という追加パラメータで指定しています。 この例では iso-2022-jp という文字コードを使っていることが 示されています。メールソフトは この指定を参照して 本文が日本語であることを知ることができます。 Content-Transfer-Encoding: は、ボディの転送形式を示しています。 7bit というのは、エンコードが 7bit モードであり、 テキストがそのまま送られていることを示しています。 長くなりましたが、これらの約束ごとを覚えて、再度メールのサンプルをみてみましょう。 本文の文字について 実際には JIS漢字コードで書かれています。 表示の都合で、文字コードが直接にはわかりませんが、 JIS漢字コード (ISO-2022-JP) になっていると理解してください。 ヘッダについてみていきます。 Subject: は、 =?ISO-2022-JP で始まり、=? で終わっています。直接みただけでは、 わかりませんが、これは先に記述した約束に従って エンコードした結果なのです。メールソフトはユーザが 読めるようにデコードして表示しています。 これが、どんな日本語の文字になるのか、試してみたいときには、 下記のように入力してみてください。(nkf コマンドをインストールしてください。 インストール方法は 各OS, ディストリビューションでの インストール方法を確認してください) > echo 'Subject: =?ISO-2022-JP?B?GyRCJUYlOSVIJWEhPCVrGyhC?=' | nkf -mBj JIS漢字をサポートした端末であれば、メールの Subject: の内容が 日本語で表示されるはずです。 逆に 日本語を エンコードしたときに どのようになるか、下記のようにして確かめることができます。 > cat sample.txt; echo '' 日本語のメールを送る方法 > cat sample.txt | nkf -MB; echo '' xvzL3LjspM6l4aG8peuk8sH3pOvK/cuh さらに、下記のように、出力された文字を nkf コマンドで デコードするともとの文字が出てきます。 > echo 'xvzL3LjspM6l4aG8peuk8sH3pOvK/cuh' | nkf -mB; echo '' 日本語のメールを送る方法 =?ISO-2022-JP?B? と ?= は、メールのヘッダで、MIMEエンコードされている部分を囲み、示すためのものです。 nkf で全体をデコードするときにはなくても問題ありません。 Mime-Veriosn: Content-Type: Content-Transfer-Encoding: というヘッダも存在することがわかります。それぞれの意味は 先に記述した通りです。 ほかにも、解説していないヘッダが存在していますが、メールのサンプルをみて、どのような形式でメールを送るのか、理解して おきましょう。 sendmail の使い方 †sendmail を使ってメールを送るときには、メールの送信先などは、コマンドラインで指定し、ヘッダと本文はパイプを通して 渡すことができます。例えば、mail.txt に入っているメールを 送信するには、コマンドラインから下記のように指定します。 cat mail.txt | /sbin/sendmail -- 送信先メールアドレス mail.txt は、サンプルと同じようにヘッダと本文を含んだテキストになります。このテキストに入っている To: は、実際の 送信先とは基本的に関係ありません。(このアドレスを参照させるオプションもあります) 送信先は コマンドラインで指定されたアドレスになります。例えば メーリングリストからきたメールでは To: がメーリングリストの アドレスのままですが、ユーザのアドレスにちゃんと配信されてくるのは、ヘッダの To: とは関係なく送信先アドレスを 指定する方法があるからです。 sendmail にはたくさんのコマンドラインオプションがあります。今回は、送信先をコマンドラインから指定する方法だけ、 解説します。 送信先を指定するときは、メールアドレスが sendmail のオプションと間違えられないよう、 -- という 特別なオプションを指定したあとに、メールアドレスを指定します。 -- のあとのパラメータは 必ずメールアドレスである ことを sendmail に指示しています。 実際に送信する方法 †それでは、実際に送信するサンプルを示します。 送信に使うデータは、Windows PCなどで編集したテキストをベースにすることを 配慮して、Shift-JISでデータを用意して、メールを送信する前に ISO-2022-JP に変換します。 Subject: の指定 †Subject: に日本語を指定するには ISO-2022-JPにしたのち Base64 に変換します。これに =?ISO-2022-JP?B? と =? を追加して ヘッダにそのまま使えるようにするスプリクトを用意します。 標準入力から、Shift-JIS漢字を読み込み エンコードした結果を 標準出力に出力します。 このスプリクトは encode_line という名前を付けて保存しておきます。 #!/bin/sh nkf=/usr/local/bin/nkf read line echo -n '=?ISO-2022-JP?B?' echo -n $line | $nkf -jMB echo -n '?=' ヘッダとボディを出力するスプリクト †実際に送信するテキストファイルを 下記の形式で準備します。このファイルは、Shift-JIS形式で保存しておきます。 最初の3行は、ヘッダに使う 送信元、送信先、サブジェクトです。 そのあとは メールの本文になります。 メールの送信元 メールの送信先 サブジェクト メールの本体 : : このファイルを 下記のスプリクトに渡して、メールのヘッダとボディの形式にします。必要なヘッダは、追加してスプリクトから 出力します。このスプリクトは、標準入力から読み込み、標準出力へ出力します。この出力結果を sendmail にパイプで渡します。 このスプリクトは prepare_mail という名前を付けて保存しておきます。 #!/bin/sh nkf=/usr/local/bin/nkf read mail_from read recpt_to read subject subject=`echo -n $subject | ./encode_line` cat << __MAIL_HEADER__ From: $mail_from To: $recpt_to Subject: $subject Mime-Version: 1.0 Content-Type: text/plain; charset=iso-2022-jp Content-Transfer-Encoding: 7bit __MAIL_HEADER__ while read line do echo `echo $line | $nkf -jS` done コマンドラインからの指定 †コマンドラインから下記のように指定すると、メールを送信することができます。shell script等の中で、下記のように記述 します。 cat mail.txt | ./prepare_mail | /sbin/sendmail -- 送信先アドレス mail.txt は 送信したいメール内容で、送信先アドレスに送信されます。 sendmail のパスはそれぞれ実行される環境にあわせて変更してください。 補足 †メールの From: や To: に漢字の名前が記入されていることがあります。今回は解説しませんでしたが、基本的には Subject: の場合と同じです。 sendmail は必要となるヘッダが足りない場合、自動的に補足してくれます。 |