原因と対策について紹介しています。
関連するページはこちら、
メール関係全体はこちら
MacOSX & Cygwin on Windows のソフトの事
Emacs 関係はこちら
Cygwin 上で、例えば、
ls -v ~/Mail/inbox.im/* | sed 's/.*/echo & \; cat & \| procmail -p -m ~\/.procmailrc/g' | /usr/bin/zsh
みたいな、シェルスクリプトで、大量のメールの振り分けを、procmail でしようとすると、固まります。
幾つか問題が有って
俄には信じ難いので、試しに、次の様なスクリプトを、~/bin/processtest.sh として保存して置いて、
#!/usr/bin/zsh
declare -i count=0
declare -i ptest
ptest=`ps -s | egrep -c '(bogofilter)|(gawk)'`
while [ $ptest -gt 0 ];
do
ptest=`ps -s | egrep -c '(bogofilter)|(gawk)'`
count=$count+1
done
echo "$count"
.procmailrc から、呼び出して見ました。
# --------------------------------------
# bogofilter の、spamicity を、ヘッダ X-bogosity として挿入
# --------------------------------------
## bogofilter で、spamicity を計算し、SPAMISITY に代入
SPAMICITY=`ruby $HOMEDIR/bin/prepare.rb | bogofilter -t --unicode=no -k 10 | gawk '{print $2}'`
BOGO_PROCESS=`zsh $HOMEDIR/bin/processtest.sh`
これを、前書きで示したスクリプトを使って、1000通位まとめて処理してみました。で、procmail のログファイルを確認してみると、殆んど、BOGO_PROCESS=0 なんですが、ほんの少し、2、3 に成っているのが有ります。
本来、SPAMCITY= のプロセスは、子プロセスが全て終了しなければ、先に進んではいけない筈なのに、gawk の出力を貰うとすぐ次ぎに進んでいる場合が有るようです。
つまり、BOGO_PROCESS= のプロセスが無ければ、procmail は、配送を済ませてさっさと終了することも有り得る訳です。
最後の fclose(stdout) の前に、fflush(stdout) を挿入。本来、fclose() は、バッファーをフラッシュしてからクローズする筈なんだけど、Cygwin の fclose() は、EOL をうまく認識できないと、フラッシュしないみたい。—> nkf
取り敢えず、mecab を使う。—> prepare-mecab.rb
先ず、スクリプトに、sh 以外を使う。経験上大差あり。
更に、先程の、~/bin/processtest.sh のループに、sleep を入れて、取り敢えず、procmail を停める。
#!/usr/bin/zsh
declare -i count=0
declare -i ptest
ptest=`ps -s | egrep -c '(bogofilter)|(gawk)'`
while [ $ptest -gt 0 ];
do
sleep 1.0
ptest=`ps -s | egrep -c '(bogofilter)|(gawk)'`
count=$count+1
done
echo "$count"
procmail を、停めてる間に、bogofilter や、gawk のプロセスが終了しない場合、強制停止させるように、TIMEOUT を設定。
# --------------------------------------
# bogofilter の、spamicity を、ヘッダ X-bogosity として挿入
# --------------------------------------
## bogofilter で、spamicity を計算し、SPAMISITY に代入
TIMEOUT=90 ## default は、960 (sec.)
SPAMICITY=`ruby $HOMEDIR/bin/prepare-mecab.rb | bogofilter -t --unicode=no -k 10 | gawk '{print $2}'`
BOGO_PROCESS=`zsh $HOMEDIR/bin/processtest.sh`
現在確認中