配置Procmail仅转发带附件邮件失败,求解决方案或替代方案
配置Procmail仅转发带附件邮件失败,求解决方案或替代方案
兄弟,我来帮你捋捋这个问题!首先说说你当前Procmail规则的问题,再给你点替代方案——毕竟你也发现了,procmail确实是老古董了,停更20多年,能用但折腾起来有点闹心。
先修复你的Procmail规则
你现在的规则是同时要求邮件头里有Content-Disposition:.*attachment和Content-Type:.*multipart/mixed,这俩是AND关系,必须同时满足才会触发转发,但很多带附件的邮件其实不满足这个组合:
- 不少带附件的邮件会用
multipart/alternative(比如同时有HTML和纯文本版本+附件),不是multipart/mixed - 还有些邮件的附件标记
Content-Disposition: attachment是在子MIME部分里,而不是主邮件头里,Procmail默认只扫主邮件头,根本抓不到
给你几个调整方向:
- 放宽匹配条件,忽略大小写
把规则改成这样,去掉对multipart/mixed的强要求,同时忽略邮件头的大小写差异(很多邮件会用小写的content-disposition):
:0 * ^Content-Disposition:.*attachment.* i * ^Content-Type:.*multipart/.* i ! where@to-forward.com
如果你想更精准,还可以加上filename=的判断——真正的可下载附件一般都会带文件名,内嵌图片这类资源可能没有:
:0 * ^Content-Disposition:.*attachment; filename=.* i ! where@to-forward.com
- 检查所有MIME子部分
如果要确保能抓到所有带附件的情况,得用formail来遍历邮件的所有MIME部分,比如:
# 先排除非多部分邮件 :0 * ! formail -x Content-Type: | grep -q 'multipart/' { :0 /dev/null } # 检查所有MIME部分里的Content-Disposition是否有带文件名的附件 :0 * formail -i "" -X Content-Disposition: | grep -qi 'attachment; filename=' ! where@to-forward.com
更现代的替代方案
既然procmail已经停更这么久了,不如换个省心的工具,给你几个实用选项:
- Python脚本+fetchmail
写个简单的Python脚本用内置的email库解析邮件,判断是否有附件,再用smtplib转发(或者直接调用本地的sSMTP)。比如核心代码大概是这样:
import email import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText def forward_if_has_attachments(email_content, to_addr): msg = email.message_from_bytes(email_content) # 遍历所有MIME部分,检查是否有带文件名的附件 has_attachments = any( part.get_filename() for part in msg.walk() if part.get_content_maintype() != 'multipart' ) if not has_attachments: return # 构建转发邮件 forward_msg = MIMEMultipart() forward_msg['From'] = msg['From'] forward_msg['To'] = to_addr forward_msg['Subject'] = f"FWD: {msg['Subject']}" forward_msg.attach(MIMEText(msg.as_string(), 'plain')) # 发送邮件(连本地SMTP服务,比如sSMTP) with smtplib.SMTP('localhost', 25) as server: server.send_message(forward_msg) # 从标准输入读取邮件内容 if __name__ == "__main__": import sys to_addr = sys.argv[1] email_content = sys.stdin.read().encode() forward_if_has_attachments(email_content, to_addr)
然后在fetchmail的配置里把MDA改成这个脚本:mda "python3 /path/to/your/script.py where@to-forward.com"
- shell脚本+munpack
用munpack(来自metamail工具包)尝试提取附件,如果能提取到就转发,脚本大概这样:
#!/bin/bash TO_ADDR="where@to-forward.com" TMP_MAIL=$(mktemp) # 读取邮件内容到临时文件 cat > "$TMP_MAIL" # 静默提取附件,成功返回0,失败返回非0 munpack -q "$TMP_MAIL" if [ $? -eq 0 ]; then # 有附件,转发 sendmail "$TO_ADDR" < "$TMP_MAIL" fi # 清理临时文件 rm "$TMP_MAIL"
给脚本加执行权限,然后fetchmail里配置mda "/path/to/your/script.sh"就行。
- Mutt自动处理
Mutt是个强大的终端邮件客户端,可以写个宏自动筛选带附件的邮件并转发,配合fetchmail把邮件拉到本地邮箱,定时运行Mutt处理就行,适合喜欢终端工具的用户。
备注:内容来源于stack exchange,提问作者Satellite One
相关产品推荐
相关产品推荐

