简体   繁体   English

如何使用 procmail 正确地将 email 的主体转换为标量变量

[英]How to correctly get body of email into scalar variable with procmail

I have the below procmail recipe that for years has faithfully worked (passed senders email and subject) to the perl script and saved the attachments.我有以下 procmail 配方,多年来一直忠实地工作(通过发件人 email 和主题)到 perl 脚本并保存附件。

FROM=""
:0
* ^FROM:.*
* ^From:[    ]*\/[^  ].*
{
       FROM=$MATCH
}
#grab the subject
SUBJECT=""
:0
* ^FROM:.*
* ^Subject:[    ]*\/[^  ].*
{
       SUBJECT=$MATCH
}

:0 ifw  #  rip & save attachements  

|ripmime -i - -d /home/carrdocs/.pmdir/attachments/ &&\
/usr/bin/perl -e 'require "/home/carrdocs/.pmdir/test_carr_subject.pl"; rename_att($ENV{SUBJECT},$ENV{FROM},$ENV{MESSAGE}); exit(0)'

:0 A
filed

I am trying to modify the recipe to also send the contents of the email's body to the perl script as a scalar variable.我正在尝试修改配方以将电子邮件正文的内容作为标量变量发送到 perl 脚本。 Accordingly, I added:因此,我补充说:

:0b w
MESSAGE=| cat 

just before the line (with one line of space between):就在该行之前(之间有一行空格):

:0 ifw 

This results in the program sometimes working as hoped to and other times failing to pass the variables and save the attachments with the error:这导致程序有时按预期工作,有时无法传递变量并保存带有错误的附件:

procmail: Program failure (-11) of "ripmime -i - -d /home/carrdocs/.pmdir/attachments/ &&\
/usr/bin/perl -e 'require "/home/carrdocs/.pmdir/test_carr_subject.pl"; rename_att($ENV{SUBJECT},$ENV{FROM},$ENV{MESSAGE}); exit(0)'"

Does anyone know how I can correctly pass the body's contents as a scalar variable to the perl script?有谁知道我如何正确地将正文的内容作为标量变量传递给 perl 脚本?

This probably happens when MESSAGE is longer than LINEBUF (or even actually when it is only slightly shorter, so that the entire ripmime command line ends up exceeding LINEBUF ).这可能发生在MESSAGELINEBUF长时(甚至实际上它只是稍微短一点,因此整个ripmime命令行最终超过LINEBUF )。

Check in the log for a message like this immediately before the failure:在失败前立即检查日志以获取类似这样的消息:

procmail: Assigning "MESSAGE="
procmail: Executing "cat"
procmail: Exceeded LINEBUF
procmail: Assigning "PROCMAIL_OVERFLOW=yes"

The assignment of MESSAGE is fine, but attempting to use its value in a subsequent recipe will fail because the string is longer than Procmail can accommodate. MESSAGE分配很好,但尝试在后续配方中使用它的值将失败,因为字符串长于 Procmail 可以容纳的长度。

So, TL;DR;所以,TL;DR; don't try to put things which are longer than a handful of bytes into variables.不要试图将超过几个字节的内容放入变量中。 (For the record, the default value of LINEBUF on my Debian test box is 2048 bytes.) (记录一下,我的Debian测试盒上LINEBUF的默认值是2048字节。)

Probably for other reasons too, refactor your recipe so that your Perl script receives the message on standard input instead.也可能出于其他原因,重构您的配方,以便您的 Perl 脚本接收标准输入上的消息。 Without exact knowledge of what ripmime does or how it's supposed to interface with your Perl script (looks to me like actually combining the two is completely crazy here, but perhaps I'm missing something), this is tentative at best, but something like如果不确切了解ripmime的功能或它应该如何与您的 Perl 脚本交互(在我看来,实际上将两者结合起来是完全疯狂的,但也许我遗漏了一些东西),这充其量只是暂时的,但类似于

:0w  #  rip & save attachements  
|ripmime -i - -d /home/carrdocs/.pmdir/attachments/
:0Afw
| /usr/bin/perl -e 'require "/home/carrdocs/.pmdir/test_carr_subject.pl"; \
     ($body = join("", <>)) =~  s/^.*?\r?\n\r?\n//s; \
     } rename_att($ENV{SUBJECT},$ENV{FROM},$body))'

I also took out the exit(0) which seemed entirely superfluous;我还取出了似乎完全多余的exit(0) and the i flag is now no longer topical for either of these recipes.并且i标志现在不再适用于这些食谱中的任何一个。

I guess you could easily inline the extraction of the Subject: and From: headers into Perl as well, with some benefits eg around RFC2047 decoding, assuming of course you know how to do this correctly in Perl.我想您也可以轻松地将Subject:From:标头的提取内联到 Perl 中,还有一些好处,例如围绕 RFC2047 解码,当然假设您知道如何在 Perl 中正确执行此操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM