メールが山のように降ってくるようになると、読む時間も ままならない(^^;;)。しかも、/var/spool/mail/$USERな どの自分のメールスプールが、ちょっと inc しないと膨 れあがり、破裂する(!)危険もある。そうでなくても、 /var が比較的小さい場合がおおい。また、xpbiffを立てて いる場合や、chsrcに、
「set mail=(60 /var/spool/mail/$USER)」
などと、設定してある場合は、「ぴっぴぴっぴ」と五月蝿い ことだろう。そこで、
『来たメールを自分のメールフォルダーに自動的に分類して放り込む』
ことが出来るのである。それは、mhook の slocal コマンドである。
# しかし、この slocal コマンドについての説明は、「man mhook」 する位しかない。しかも、ちょっと書き間違えると、メールが 「迷子」になったり、「ロスト」したりしてしまう、危険なコマン ドでもある。
## mh-6.8.X では man slocal で大丈夫:-)。
そこで、私の失敗と現在の設定とを、読んで貰うだけでも、何らかの 役には立つと思うので、書いておく。
「slocal」を用いるには、「~/.forward ファイルの書き換え」と、 「.maildelivery」の設定の2つの手順で行なわれる。
~/.forward
::>> "| /usr/local/lib/mh/slocal -user hayashi"
こうすることで、来たメールを、「|」で slocal に喰わせることが 出来る。 (尚slocal起動の際、上述のようにオプションで user を指定しておくこと)
# 勿論、.maildelivery の設定後に変更すること!!。
slocal は、~/.maildelivery ファイルに記述してあるように動作する、
## 但し、残念(?)乍ら、私は今までに一度も経験したことはありませんが:-)
## 1日50〜100通位届くのが3年以上続いていますが。
## ちゃんと mail のログ(smtp connection)を tail -f で常時見てますし:-)
## まぁ、OSの flock/lockf の問題じゃないかと思いますが:-)
それと、.mh_sequence が勝手に:-)更新されるので、
mh等で未読メールを読んでいるのと、変にぶつかったりすることも、
稀にあるようです。
.maildelivery ファイルの各行のフォーマットは、
field pattern action result string
である。それぞれの意味は…(man 参照)、
::>> # from postmaster
::>> From postmaster | A "/usr/local/lib/mh/rcvstore +Pm"
::>> To postmaster | A "/usr/local/lib/mh/rcvstore +Pm"
ヘッダの「From」行か「To」行が、「postmaster」だったら、 mh附属のrcvstoreというユーティリティーツールで、「Pm」という フォルダ(但し、.mh_profileで 「Path:Mail」としてあれば、 ~/Mail/Pm となる)に放り込む。
んで、「result」が「A」なので、このPmに放り込まれたメールは、 .maildelivery の他の検索項目に対し、「このメールは既に配送さ れた」という扱いになる。
::>> # for Maling List
::>> X-Ml-Name 98ml | A "/usr/local/lib/mh/rcvstore +98"
これも上記と同様。 ML(Mailimg List)から来るメールの場合は、メールヘッダに識別 し易い特別な「行」がつけてあることが多い。例の場合では、ヘッダ に「X-Ml-Name: 98ml」という行が付けられたメールが送られてくる から、ここをキーワードにして、検索を行なっている。
::>> # Personal
::>> From hal | ? "/usr/local/lib/mh/rcvstore +Hal"
さて、ここも同様。「hal」さんから来るメールは、ヘッダに 「From: ... hal ..」とついているので、これをキーワードにして 検索をしている。 しかし、「result」が「?」である。 これは、上の98mlに「hal」さんも加入しているので、98mlのメール のうち、「hal」さんの出したメールに、「From: ... hal ...」と ついてしまっている場合、ここも「A」としておくと、98mlの「hal」 さんのメールも、「Hal」に放り込まれてしまうのである。 (つまり届いた1通が2つのフォルダーに放り込まれる)
そこで、「?」にしておくと、「配送されていないメールについてのみ、 動作を行なう」のであるから、98mlでのメールは「Hal」には放り込まれ ないで、「Hal」さんからの直接のメールのみが、放り込まれるのである。
::>> # default
::>> default - | ? "/usr/local/lib/mh/rcvstore +inbox"
設定に最低限必要なのは、最後の1行だけである。 つまり上記以外のメールは、「inbox」に放り込む、という設定である。
# 注意すべきは、パイプで起動されるのが「bourne shell」であり、 コマンドやファイルなどには、きっちり絶対パスを書いておかないといけない、 ってことと、届いたメールは標準入力として渡される、ということ である。
ということでこの.maildelivery ファイルを上手に利用すれば、 届いたメールに対してさまざまなactionをすることが可能である。
もちろん例で説明した以外にも、メールの差出人によって、「お返 事メールを自動的に出す」とか、「全然読まずに捨ててしまう:-P」 とか、「メールフォルダーに放り込まずに、ファイルとして落す」 とかが出来ます。いろいろ試してみて下さい。
# で、この.maildelivery ファイルを間違って書いていると、メール がロストとしたりするので、テストの間は、~/.forwardを
::>> \hayashi, "| /usr/local/lib/mh/slocal -user hayashi"
と、普通に配送するのと、Mhに喰わすのと、2つにフォワードして
テストを行なうとよい。
--
/* はやし☆はるひさ (hayashi@kuic.kyoto-u.ac.jp) 京大・分子・中西研 */
多少改定 10May1995 by はやし はるひさ
% cat メールファイル | /usr/local/lib/mh/slocal -verbose -user hayashi
して試しましょう。verbose オプションをつけると、詳細情報が帰ってきます。
また、気をつけねばならないのは、.forward で プログラム(slocal)に メールを喰わせている、という点です。これにより、 sendmail.cf 中の ローカル配送指定の Mlocal でなくて、Mprog の行が使用されます。
つまり、届いたメールを jis から euc に変換しているサイト等では、 ローカル配送の際に、漢字コード変換 filter を噛ませているのですが、 slocal を使用しつつ、そういう操作を必要とする場合は、なんらかの フィルターを自分で slocal の前に噛ます様に工夫して下さい。
例えばうち(今のとこね:-))の場合、日本語 Solaris2.3 に 日本語Openwindows 3.3 で、日本語 vi を使う人が居る(;_;)ので、ローカル配送は、j2email という jis->euc 変換フィルタ+個別配送プログラムを使用しています。 しかし、slocal はプログラム起動ですので、下の Mprog 行、つまり /bin/sh が起動されます。(のでslocalでのメールは jis のまま届きます)
## 私一人、X11R6+twm+kterm+mule+mh だもんなぁ…(愚痴)。
ってことで、slocalが張れてしまいました(笑)。
これで届いたメールは自動的に分類され、メール
フォルダーに放り込まれるんだな。
で、これで、/var/spool/mail の個人メールスプール は、常に 0 のままで、/var の容量に影響を与えないで 良いのだけれど、こんどは、自分のディレクトリが 増えていきます。勿論このことはよ〜く気をつけるように。
で、届いたのはいいものの、さて、どうやって 「メールが届いた」ことを知ることが出来るんだろうか…。
そこで、.mh_profile に設定した 「Unseen-Sequence: unseen」 がここで効いてくるのである。これを設定すると、各フォルダー の .mh_sequences に、
::>> unseen: 1-6
とかいうように、未開封のメールを記録してくれるんだな。 こいつを grep してやれば、いいわけだ。
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- um.sh
#!/bin/csh -f # # um.sh -- scaning Unseen Mails. # Original: by Haruhisa Hayashi=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-# Modified: by Katsumi Ohta # onintr brk # public setting set fname_pth=`mhpath +` set fname_dir=`folders -fast` set fname_seq=.mh_sequences set seq_name=`grep Unseen-Sequence: $HOME/.mh_profile | sed -e 's/^.*: //'` # set mhform_inbox="unseen2.form" set mhform_other="unseen1.form" @ unseen_num = 0 foreach folder ($fname_dir) grep $seq_name $fname_pth/$folder/$fname_seq >& /dev/null if ($status == 0) then echo "<< Unseen Mail >> in +"$folder if ($folder == "inbox") then set mhform = $mhform_inbox else set mhform = $mhform_other endif scan +$folder $seq_name -form $mhform | tee -a /tmp/scan.$$ endif end if (-f /tmp/scan.$$) set unseen_num = `wc -l < /tmp/scan.$$` switch ($unseen_num) case 0: echo " You've already seen all of your mail." breaksw case 1: echo " You have only one unseen mail." breaksw default: echo " You have $unseen_num unseen mails." breaksw endsw brk: rm -f /tmp/scan.$$ exit 0;
um.sh は、私が書き殴って(笑)、某友人が汎用に書き直してくれた シェルプログラムである(→ um.sh を get )。 未開封メールが、どのフォルダーに何通あるか表示してくれる。
grep するんだが、その前に……、
::>> set fname_pth=`mhpath +`
で、Mhのメールパス(つまり .mh_profileで指定した「Path」)を 環境変数としてgetしている。
::>> set fname_dir=`folders -fast`
これは、メールフォルダーの名前を get している。
::>> set seq_name=`grep Unseen-Sequence: $HOME/.mh_profile | sed -e 's/^.*: //'`
ここでは、Unseen-Sequence として、何の文字を使用しているかを getしている。(私の場合、「unseen」である)
# このように一般性を持たせると、実行速度が遅くなるので、 最初から判っているものは、直接与えておくほうが速い。
::>> # private setting
::>> set fname_pth=/home/usr2/hayashi/Mail
::>> set fname_dir=( inbox 98ml Hal Postmaster )
::>> set seq_name=unseen
と、上記の部分を置き換えている。
あとは、
::>> set mhform_inbox="unseen2.form"
::>> set mhform_other="unseen1.form"
では、「inbox」を見る時と、他のフォルダーを見る時では、 使用するmh-formatファイルを変更しているだけである。 (別に同じものでもいいし、さらに拡張しても可能である。)
# ま、適当に改良してね(^^;;)。
さてさて、これで slocal も張れたことだし、ま、一通りのことは 出来るとおもうけどね。 あとは、色々自分で試して下さい。
--
/* はやし☆はるひさ (hayashi@kuic.kyoto-u.ac.jp) 京大・分子・中西研 */
多少改定 10May1995 by はやし はるひさ
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- um.pl
#!/usr/local/bin/perl # um -- scanning Unseen Mails. # Original: by Haruhisa Hayashi=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-# Modified: by Katsumi Ohta # um.pl # Original: by KAWAMOTO Yosihisa $HOME = $ENV{'HOME'}; $MH = $ENV{'MH'}; # private setting $path = "$HOME/Mail"; $unseen = 'unseen'; @folders = split(/ /, 'inbox News Postmaster 98ML'); $ignores = ' alt comp fj jp ku rec '; $form_inbox = 'unseen2.form_mime'; $form_other = 'unseen1.form_mime'; # public setting $MH = "$HOME/.mh_profile" if ($MH eq ''); if ($path eq '' || $unseen eq '') { open MH || die "Do you use MH??\n"; while ( ) { $path = "$HOME/$1" if ($path eq '' && /^Path: (.*)$/i); $unseen = $1 if ($unseen eq '' && /^Unseen-Sequence: (.*)$/i); } } @folders = grep(-d && s/.*\///, <$path/*>) if (0+@folders == 0); $mh_seq = '.mh_sequences'; $unseen_num = 0; foreach $folder (@folders) { next if ($ignores =~ / $folder / || ! -d "$path/$folder"); open(MH_SEQ, "$path/$folder/$mh_seq") || next; @_ = ; if (0+grep(/^$unseen: /, @_) > 0) { print "<< Unseen Mail >> in +$folder\n"; if ($folder eq 'inbox') { $form = $form_inbox; } else { $form = $form_other; } $scan = "scan +$folder $unseen"; $scan .= " -form $form" if ($form ne ''); if (open(SCAN, "$scan |")) { while ( ) { print; $unseen_num++; } close(SCAN); } } close(MH_SEQ); } if ($unseen_num == 0) { print " You've already seen all of your mail.\n"; } elsif ($unseen_num == 1) { print " You have only one unseen mail.\n"; } else { print " You have $unseen_num unseen mails.\n"; } exit 0;
単に folder を探して(.mh_profile にある Path: オプションの ディレクトリの下を全部掘ります。時間がかかるので、$ignores に 指定すれば、そのメールフォルダは無視します)、それぞれのメール フォルダについて、.mh_sequence から unseen を見つけ、 inbox フォルダなら unseen2.form_mime で、 他のフォルダーなら unseen1.form_mime (共に Path: のディレクトリに。) という mh-format ファイルで scan しているだけです。
um.sh と同じく、一般性を持たせると、実行速度が遅くなるので、 最初から判っているものは、直接与えておくほうが速い。 つまり、public setting を全部コメントアウトし、 @folders に、調べたいメールフォルダを全部記述しておくとよい。