0

我有以下场景:

GNU/Linux 机器上的 SMTP 服务器正在接受邮件。已接受的邮件正在发送到 procmail 以进行进一步处理。这是我的.procmailrc

VERBOSE=yes
LOGFILE=$HOME/procmail.log
SUBJECT=`formail -xSubject: | tr -d '\n' | sed -e 's/^ //' | /usr/bin/perl -MEncode -ne 'print encode ("utf8",decode ("MIME-Header",$_ )) '`
FROM=`formail -rt -xTo:`
DATE=`formail -xDate:`
BODY=`formail -I ""`
:0fbW
* ^From.*some_special_name@special_server.com
| echo "FROM:$FROM" > $HOME/res.txt; \
  echo "DATE:$DATE" >> $HOME/res.txt; \
  echo "SUB:$SUBJECT" >> $HOME/res.txt; \
  echo "BODY:" >> $HOME/res.txt; \
  echo $BODY >> $HOME/res.txt; process.py

这个小脚本首先创建一个本地文件$HOME/res.txt,然后启动另一个名为process.py的脚本。现在,$HOME/res.txt填充了以下条目:

FROM:some_special_name@special_server.com
DATE:Mon, 06 Oct 2014 13:14:32 +0200
SUB:Some subject
BODY:
This is a multi-part message in MIME format. --------------030006020609010705060803 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Hello, Some kind of long tekst where I cannot see the line feed chars nor any other control chars...

正文包含没有正文的原始格式的原始字符串。我的意思是过滤掉 \n 或 \t 字符。process.py脚本要求消息的正文部分保持电子邮件消息的原始格式。

我怎样才能做到这一点?

4

1 回答 1

1

与 shell 脚本中的往常一样,您需要正确地对变量进行双引号引用,除非您特别要求 shell 对值执行标记拆分和通配符扩展。有关详细说明,请参见例如此答案

  echo "$BODY" >>$HOME/res.txt; \

另外,我不明白你为什么要混合这样的多个动作。字里行间,我猜你的意思是process.py读取res.txt而不是标准输入;如果它正在读取标准输入,它将收到正确的、未损坏的消息。

没有上下文,我会四处走动并推测该f标志也是错误的。除非process.py在标准输出上打印一条新消息,它应该替换 Procmail 配方文件其余部分的传入消息,否则您应该简单地将其取出。

这里还有一个竞争条件:如果多条消息大致同时到达(如果您的系统负载过重,“同一时间”可能是一个相当宽的窗口),它们将覆盖res.txt并践踏彼此的结果,导致不可预测方法。对此的习惯解决方案是使用本地锁定文件;但非常优越的解决方案是消除对临时文件的需求,并进行更改process.py以改为读取标准输入。

由于您无论如何都在使用 Python,所以我将在 Python 中进行所有标头解析,但可能的例外是formail -rtzxTo:,这对于重新实现相当复杂;这将显着简化您的 Procmail 配方,并可能改进process.py(或您创建的包装器,如果您无法修改它)。

于 2014-10-07T09:56:00.687 回答