配置 procmail 以在过滤电子邮件时匹配外部电子邮件地址列表

Configure procmail to match an external email address list when filtering emails

我的 fetchmail 脚本从电子邮箱中检索电子邮件并将它们放入一个名为 mario 的文件中,然后将其转储到我的 /var/mail/ 文件夹中。我正在尝试设置一个 procmail 脚本来处理 mario;通过处理,这就是我的意思:procmail 脚本应该针对包含已知电子邮件地址列表的外部文本文件 (fromlist) 进行过滤。一旦匹配 mario/fromlist,消息就会从 mario 中提取并存储到我的本地 nbox/ 文件夹中。

在网上,我找到了一段代码,包括一个配方,我已经输入到我的 procmail 控制文件 (.procmailrc) 但它似乎没有正在工作。这是代码:

FROMFL=$MAIL/fromlist

FROMLS=formail -xFrom: | sed -e 's/*(.*)//;s/>.*//;s/.*[:]*//'`

:0

* ? fgrep -xi $FROMLS $FROMFL

$MAIL/inbox

我想我已经解决了 sed(见我的问题 ),但我仍然无法解决 formailfgrep 部分。所以当我 运行 procmail 脚本时,我获得的日志是:

$ mailstat var/log/procmail.log
/bin/sh: 0: Can't open fgrep
/bin/sh: 1: grep: not found
/bin/sh: 1: sed: not found
/home/user/var/mail/reginbox/
procmail: [6880] Sat Jun 16 16:57:32 2018
procmail: Acquiring kernel-lock
procmail: Assigning "FROMFL=/home/user/var/mail/fromlist"
procmail: Assigning "FROMLS="
procmail: Assigning "LASTFOLDER=/home/user/var/mail/reginbox/msg.XXX"
procmail: Assigning "SHELL=/bin/sh"
procmail: Executing "fgrep,-xi,/home/user/var/mail/fromlist"
procmail: Executing "formail -xFrom: | sed -e `'s/.*<//; s/>.*//'`"
procmail: No match on "fgrep -xi /home/user/var/mail/fromlist"
procmail: Non-zero exitcode (127) from "fgrep"
procmail: Notified comsat: "user@0:/home/user/var/mail/reginbox/msg.XXX"
procmail: Opening "/home/user/var/mail/reginbox/msg.XXX"

看起来好像 formail 不能完全提取 "From:" 所在的行,这意味着这些行中的电子邮件地址没有被 SED 命令从其余部分中分割出来,也没有与包含电子邮件列表(来自列表)的文本文件,这就是日志显示 "No match" 消息的原因。

我怎样才能找出这些东西出故障的地方?

运行 外部命令的语法是

VARIABLE=`command to run`

您缺少开头的反引号,因此您 运行 有效

FROMLS="formail"
-xFrom: | sed etc is a syntax error

无论如何,提取发件人的方法有点不准确,因为它不能正确处理电子邮件地址格式的各种变化。一个更健壮但更难理解的解决方案是

FROMLS=`formail -rtzxTo:`

这使得 formail 生成回复 -rt,然后 从生成的回复中 提取 To: 地址,当然现在指向返回给原始发件人。根据设计,formail 在生成回复时仅将输入消息发件人的实际电子邮件地址放入 To: header,因此这就是您要提取的内容。

除此之外,您的脚本在技术上应该可以提取匹配的消息并将它们复制到您想要的目标文件夹。这是一个快速演示:

tripleee$ cd /tmp

tripleee$ echo moo@example.com >fromlist

tripleee$ cat one.rc
# temporary hack
SHELL=/bin/sh
MAILDIR=/tmp
MAIL=.
VERBOSE=yes

FROMFL=$MAIL/fromlist

FROMLS=`formail -rtzxTo:`

:0
* ? fgrep -xi "$FROMLS" "$FROMFL"
$MAIL/inbox


tripleee$ procmail -m one.rc <<\:
From: ick@example.com
To: poo@example.org
Subject: no match

hello
:
procmail: [16406] Wed Jun 27 13:41:35 2018
procmail: Assigning "FROMFL=./fromlist"
procmail: Executing "formail,-rtzxTo:"
procmail: Assigning "FROMLS=ick@example.com"
procmail: Executing "fgrep,-xi,ick@example.com,./fromlist"
procmail: Non-zero exitcode (1) from "fgrep"
procmail: No match on "fgrep -xi ick@example.com ./fromlist"
 Subject: no match
  Folder: **Bounced**                                                        61

tripleee$ procmail -m one.rc <<\:
From: moo@example.com
To: poo@example.org
Subject: match

hello
:
procmail: [16410] Wed Jun 27 13:41:37 2018
procmail: Assigning "FROMFL=./fromlist"
procmail: Executing "formail,-rtzxTo:"
procmail: Assigning "FROMLS=moo@example.com"
procmail: Executing "fgrep,-xi,moo@example.com,./fromlist"
procmail: Match on "fgrep -xi moo@example.com ./fromlist"
procmail: Assigning "LASTFOLDER=./inbox"
procmail: Opening "./inbox"
procmail: Acquiring kernel-lock
 Subject: match
  Folder: ./inbox                                                            68    

procmail 无法从输入文件夹中删除任何内容。如果你想这样做,一个常见的解决方案是让 Procmail 将 non-matching 消息写入另一个输出文件夹,然后将其复制回输入文件。最终效果是来自原始输入文件夹的消息现在被分成两个文件,一个具有匹配项,一个具有 non-matching 条消息。