【问题标题】:Configure procmail to match an external email address list when filtering emails过滤电子邮件时配置 procmail 以匹配外部电子邮件地址列表
【发布时间】:2018-06-16 16:30:52
【问题描述】:

我的 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(请参阅我的问题Sed command and unknown patterns found online),但我仍然无法解决 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 似乎无法完全提取“发件人:”所在的行,这意味着这些行中的电子邮件地址不是由 SED 命令从其余部分中提取出来的,也没有与文本文件进行比较电子邮件列表(发件人列表),这就是日志显示“不匹配”消息的原因。

我怎样才能知道这些东西在哪里坏掉了?

【问题讨论】:

  • 我们无法真正猜出您的 mailstat 脚本中的内容,但我猜它要么有我在回复中概述的错误,要么您搞砸了 PATH 变量所以它找不到它需要的命令。
  • Mailstat 解析 procmail 日志并显示有关传递到所有文件夹的消息(总大小和平均大小以及消息数量)的摘要。
  • 但错误消息似乎来自其中;您发布的 Procmail 配方甚至不包含 grep 命令。
  • @tripleee 我已经尝试过你的建议(formail -rtzxTo:)。另外,我已将第二位更改为 > 这样 FROMLS 现在是 formail -rtzxTo: | grep -EiEio '\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b'。如果在命令行上单独运行这两个命令,则它们可以工作,但如果通过管道相互连接,它们似乎不起作用。 FROMLS 仍然没有被分配给任何东西,如上面的日志所示,因此是“不匹配”。如何将 FROMLS 分配给某事?
  • grep 根本不需要。您是为了幽默而反复提供相同的标志,还是您认为这会产生一些影响?大多数grep 方言不支持\b。但是完全删除grep 显然也会摆脱这些错误。正确的代码已经发布在我的答案中,并解释了它是如何工作的。

标签: email sed procmail


【解决方案1】:

运行外部命令的语法是

VARIABLE=`command to run`

你错过了开头的反引号,所以你正在有效地运行

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

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

FROMLS=`formail -rtzxTo:`

这使得formail 生成回复-rt,然后从生成的回复中提取To: 地址,这当然现在指向原始发件人。按照设计,formail 仅在生成回复时将输入消息发件人的实际电子邮件地址放在 To: 标头中,因此您将提取该地址。

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

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 将不匹配的消息写入另一个输出文件夹,然后将其复制回输入文件。最终效果是来自原始输入文件夹的消息现在被划分为两个文件,一个包含匹配的消息,一个包含不匹配的消息。

【讨论】:

  • 在回答您关于如何运行外部命令的回答时,我不得不说缺少的开头反引号是它应该在 procmail 控制文件中的位置,我不太清楚为什么我错过了输入它进入问题,因为我从命令行复制了粘贴的命令。
  • 感谢有关使用这些标志并从“收件人:”而不是“发件人:”标题中提取电子邮件的建议。我会立即解决这个问题。
  • 目前,我启动了一个脚本,该脚本调用 procmail 来处理输入文件(“/var/mail/mario”),该文件之前由 fetchmail 检索。在这个脚本中,我有“cat mario >> .newfile”和“formail -s procmail
  • 是的,这正是它所描述的。
  • (请注意演示 sn-p 中的严格引用,尽管我认为它对您正在测试的特定地址没有影响。)
猜你喜欢
  • 2014-09-11
  • 2016-03-20
  • 2014-12-13
  • 1970-01-01
  • 1970-01-01
  • 2016-11-29
  • 1970-01-01
  • 2016-11-15
  • 1970-01-01
相关资源
最近更新 更多