rcmdnk's blog
Last update

メーラーだえもんさんへの手紙

Mavericksにアップデートしてからmailコマンドが使えなくなってたのを 直したのでついでに設定についてもまとめておきます。 前提としてpostfixが入ってる事が必要になりますが、 最近のMacであればデフォルトで入っていると思います。

メールの設定

以下ではGmailのSMTPサーバーを使います。

まずはGmailアカウント情報のデータベースを作成。

$ cd /etc/postfix/
$ sudo vim gmail_passwd

として、gmail_passwdというファイルを中身を以下の様にして作ります。

smtp.gmail.com:587 [email protected]:password

userpasswordは自分の物を。 違うSMTPサーバーを使いたい場合は適時変更。

作成後、

$ sudo postmap gmail_passwd

とすると、gmail_passwd.dbというデータベースファイルができているはずです。 これでもうgmail_passwdはいらないので、パスワードも書いてあるので消しておきます。

$ sudo rm -f gmail_passwd

次に、このデータベースの登録を含めたPostfix等の設定を /etc/postfix/main.cfに書き込みます。

$ sudo vim main.cf
/etc/postfix/main.cf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
## Posifix Configuratoins
mynetworks = 127.0.0.0/8
mydomain_fallback = localhost
inet_protocols = all
recipient_delimiter = +
relayhost = smtp.gmail.com:587

#SASL Authentication
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/gmail_passwd
smtp_sasl_security_options = noanonymous

#TLS Settings
smtp_use_tls = yes
smtp_tls_security_level = encrypt
tls_random_source = dev:/dev/urandom

こんな感じで。

追記: 2014/05/02

新しいサラの環境で見てみたら、

mynetworks = 127.0.0.0/8
mydomain_fallback = localhost
inet_protocols = all
recipient_delimiter = +

これらの設定はすでにデフォルトのmain.cfに書かれてました。 ので、relayhost以下だけを加えればOK。

追記ここまで

最後に

$ sudo postfix reload

として、postfixをリロードしてあげればOK。

まだ走っていなくて

postfix/postfix-script: fatal: the Postfix mail system is not running

と言われたら

$ sudo postfix start

としてあげればOK。

postfix: fatal: chdir(/Library/Server/Mail/Data/spool): No such file or directory

以下はちょっと勘違い。


と、以前、この設定をしたままLionからMavericksにアップデートしたんですが、 メールを送ろうとすると

postfix: fatal: chdir(/Library/Server/Mail/Data/spool): No such file or directory

とのエラーが。実際、このディレクトリが無いので、

$ sudo mkdir -p /Libary/Server/Mail/Data/spool
$ sudo postfix set-permissions

として作ります。postfix set-permissionsはpostfix関連のディレクトリの パーミッションを一通り整えてくれます。 整えた後で、sudo postfix reload(start)を行えばOK。

もし、上記の作業中に

postfix/postfix-script: warning: group or other writable: /Library/Server/Mail/Data/mta

という警告が出た場合、mtaディレクトリのパーミッションがおかしい(グループの人が書き込める)ので、

$ sudo chmod g-w /Library/Server/Mail/Data/mta

としてグループのパーミッションを奪ってあげれば警告が消えるはずです。

$ sudo postfix check

とすると、postfixの状態をチェックすることが出来ます。 (問題ないなら何も出ない。)


ここまで勘違い。以下追記。

追記: 2013/11/15

問題は、どうやらMountain LionからPostfixのディレクトリが変更されたことのようです 1

元々、Lionまでは/etc/spool/main.cf

queue_directory = /Library/Server/Mail/Data/spool

と書いてあり、さらに /System/Library/LaunchDaemons/org.postfix.master.plist と言うファイルがあり、この中身に

1
2
3
4
<key>QueueDirectories</key>
<array>
    <string>/Library/Server/Mail/Data/spool/maildrop</string>
</array>

こんな感じで同じディレクトリの/postfix/maildropが指定されています。

これが重要で、Macは launchd というサービス管理を採用していて、 これが色々サービスを自動で立ち上げたり閉じたりしてくれるんですが、 postfixに関しては、このmaildropディレクトリにmailコマンドによって queが投げ込まれると、launchdがpostfixを立ち上げて メールを送信できるようになる、という仕組みになっています。

従って、わざわざ自分でpostfixをスタートさせたりする必要はありません。

ただ、このディレクトリが、Mountain Lion以降変更され、 org.postfix.master.plistはこんな感じになっています。

org.postfix.master.plist
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>org.postfix.master</string>
    <key>Program</key>
    <string>/usr/libexec/postfix/master</string>
    <key>ProgramArguments</key>
    <array>
        <string>master</string>
        <string>-e</string>
        <string>60</string>
    </array>
    <key>QueueDirectories</key>
    <array>
        <string>/var/spool/postfix/maildrop</string>
    </array>
    <key>AbandonProcessGroup</key>
    <true/>
</dict>
</plist>

maildropディレクトリが/var/spool/postfix/maildropに変わっています。 こちらを覗いてみると確かにディレクトリが用意されていました。

従って、LionMavericksとした時に、 /etcにあるファイルなどはそのまま保存されて設定が引き継がれた様ですが、 /System/Library/等にある設定はOSの根幹となるためか 一通り刷新される様です。

ちょっと別の話でNo-IP のデーモンが上手く起動してないようなんですが、 多分この辺が関係ありそう。

ともかく、ディレクトリが変わったのでせっかく上でmain.cfに従ってディレクトリを作ったものの問題が。 このままだとlaunchdが監視してるディレクトリとは違う所にqueを送り込むので postfixを手動で起動させない限りメールが送られません。

実際に、設定してから暫くは良しとしてて、ふときちんと送られて無いことに気づきました。 (手動でpostfixを起動したのでMacを再起動させる時まではずっと動いていた模様。)

そこで、launchdにきちんと管理してもらえるようにmain.cfの方をMavericksに対応させるように書き直します。 もし、postfixを主導で立ち上げてる場合は一度切っておきます。

$ sudo postfix stop

/etc/postfix/main.cfの以下の二つの値を変更します。

main.cf
1
2
3
4
5
-queue_directory = /Library/Server/Mail/Data/spool
+queue_directory = /var/spool/postfix
---
-data_directory = /Library/Server/Mail/Data/mta
+data_directory = /var/spool/postfix

設定後、パーミッションを整え、確認のコマンドを。

$ sudo postfix set-permissions
$ sudo postfix check

/var/spool/postfixを何もいじってなければ上手く行くと思いますが、 何かパーミッションがおかしいような時は出た注意に従って治すように。

これで、/Library/Server/Mailの方は要らなくなったので、 余計な物は消しておきます。 (もし、なんらか他のものが使ってる可能性があるような場合は注意して、 無理して消す必要はありません。)

$sudo rm -rf  /Library/Server/Mail

OK。

launchdを再起動させます(必要ないかも)。

$ launchctl stop /System/Library/Launchdaemons/org.postfix.msater.plist
$ launchctl start /System/Library/Launchdaemons/org.postfix.msater.plist

もし、これでも上手くいかない場合は一度Mac自体再起動してみてください。

自分のとこでは色々ディレクトリを間違えたりしたので

postfix/postdrop[94917]: warning: mail_queue_enter: create file maildrop/169833.94917: No such file or directory

みたいなWarningが出たりがちゃがちゃしてしまいましたが、 きちんと設定して再起動したらうまくいきました。

これでpostfixが自動で起動するようになっているはずです。

ちなみに、上の org.postfix.master.plist の中身ですが、

  • Label: ジョブのラベル。
  • Program: 実行させるプログラムへのパス。
  • ProgramArguments: プログラムの引数。1つ目の引数はプログラム名 2。 残りがプログラムに対する引数で-e 60とすると、postfixは起動から60秒で自動的に停止する。。
  • QueueDirectories: このディレクトリをlaunchdが監視し、ファイルが出来たりしたら このジョブを開始する。
  • AbandonProcessGroup: 通常はジョブが死んだ時に同じプロセスグループの プロセスをlaunchdが全てkillする。AbandonProcessGroupをtrueにしておくと これをしないようにする。

といいった感じ。つまり、ホントに必要なときだけpostfixを起動するような設定です。 逆に-e 60を除けば一度立ち上がれば立ちっぱなしです。

KeepAliveと言うオプションを使うと、ネットワーク状態や 他のジョブの状態を確認しながら走り続けるかどうか決められたりもするので、 これを使えばネットにつながってる時だけ走り続けさせる、 みたいなことも割りと簡単に出来そうです。

チェックについても下のテストの項目の最後に追記。

追記ここまで

テスト

$ echo test mail from Mac! | mail -s test [email protected]

などして適当なメールアドレスに送って届けばOKです。

もし上手く届かない場合は/var/log/mail.log に送信ログがあるのでこれをチェック。

...postfix/smtp[90550]: error: open database /etc/postfix/gmail_passwd.db: No such file or directory

みたいなエラーがあればmain.cfに書いたデータベース名が間違ってるか、 ファイルが正しく作られてません。

メールコマンドでアドレスを渡す事でメールが遅れます。上記の様に内容をパイプで渡すか、直接起動して

$ mail [email protected]
Subject: test
test mail from Mac!

.
EOT
$

のように書いていきます。 (Subject:は勝手に出るので件名を書き込んでReturnすれば内容行へ。 内容の最後に.だけの行を書いてReturnすると 送信されます。)

追記: 2013/11/15

launchdでの設定を正しくお此方たと、postfixが動いてない状態で mailを送ってみると、送った直後に/var/log/mail.logで、

...postfix/master[4932]: daemon started -- version 2.9.4, configuration /etc/postfix

みたいなメッセージが確認できるはずです。

また、暫くしてからみてみると、メールを送ったりするログの後、

...postfix/master[8453]: master exit time has arrived

こんな感じできちんと終了していることが分かると思います。

これで自動でpostfixが立ち上がり、メールも送られ、 postfixは必要がない時は止まっている状態になっているはずで、 今後はMac起動時から気にせずにメールを送れる様になります。

追記ここまで

良く使うところ

mailコマンドを最もよく使うのは、cronなんかで自動実行させている 時に、何かあったら知らせる、ということだと思います。

各実行ファイルでmailコマンドを記述しても良いのですが、 以下の様なラッパースクリプトを作ってcronで設定するときに噛ませておくと便利です。

cronWarpper.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/bin/bash
. ~/.bashrc

###########################
# cron tab example
# ------------------------
# # settings
# SHELL=/bin/bash
# PATH=$HOME/usr/bin:$PATH
# [email protected]
# # min hour day/month month day/week machine command
# #########################
# # weekly
# 10 1 * * 0 cronWrapper echo weekly at 1:10 Sunday!
# # daily
# 00 15 * * * cronWrapper echo daily at 15:00!

# mail setting
mailto=""
if [ -f ~/.mailto ];then
mailto=`grep MAILTO ~/.mailto|cut -d= -f2`
  mailto=`eval echo $mailto`
fi

crontmp=.cron.$HOSTNAME.$PPID
$@ >$crontmp 2>&1
if [ -s $crontmp ];then
node=`hostname`
  exe=`basename $1`
  shift
if [ "$mailto" != "" ];then
cat $crontmp | mail -s "$exe $@ at $HOSTNAME CRONINFORMATION" $mailto
  else
cat $crontmp
  fi
fi
rm -f $crontmp

Original Script: cronWrapper

どんな実行コマンドでも、もし、何かエラーでも標準出力でも出力があれば メールを送ります。

追記: 2014/06/19

単にCronのファイルに[email protected]を加えておけば 何か出力があればメールを送る、ということは出来るのに、 なぜこんなのを作ったのか謎。 単に知らなかったのか、知らない割にスクリプト内にMAILTO=について書いてあるので、 何か意味があった気がしないでもないですが(単にタイトルを整形したかっただけ?)、 必要性がわからなくなったので暫く外してMAILTOでやってみることに。

追記ここまで

大概このメールはフィルターで余り見ない所に入れておいてますが、 全てを毎回送るようにしてしまうと流石に怠いので、 出力があるものだけを送るように。

ホントに必要な警告メールについては別途、各実行コマンドの中で送るようにしています。

Evernoteへコマンドラインから送る

コマンドラインから作業している時にファイル内容をメモしておきたいとか、 一応何かの時の為に内容を残しておきたい、などという時に ファイルを適当なフォルダ等に残しておくよりは Evernoteへサクッと送って置いた方が後から検索とかも簡単に出来るので何かと便利です。

というわけで、こんなスクリプトを作ってevernote_mailへ送っています。

evernote_mail

コマンドラインからEvernoteへ送るスクリプト

基本的には

$ evernote_mail -f file

とすると、ファイル名がタイトルで内容がファイルの中身のノートが Evernoteに作られます。

ちょっとしたスクリプトや設定ファイルなんかを取り敢えずとっておいたり するのに便利なので、よかったら使ってみてください。

Sponsored Links
  1. Mountain LionでPostfixの設定が変わった

  2. マニュアルにもあるようにちょっと勘違いしやすい。 特に、Programが省略された時にProgramArgumentsの第一引数が実行ファイルとして 使われる、とあるので、じゃあProgramがある時はProgramArgumentsの 最初の項はプログラムに対する第一引数を入れるのか、というと、違う、と言う辺り。。。

    • launchd.plist(5) Mac OS X Manual Page
    • execvp(3) Mac OS X Developer Tools Manual Page
Sponsored Links

« 怪しげなのに良く検索に引っかかってしまうサイト: プログラム問答 ja.softuses.com Cgywinからメールを送る »

}