You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

配置Procmail仅转发带附件邮件失败,求解决方案或替代方案

配置Procmail仅转发带附件邮件失败,求解决方案或替代方案

兄弟,我来帮你捋捋这个问题!首先说说你当前Procmail规则的问题,再给你点替代方案——毕竟你也发现了,procmail确实是老古董了,停更20多年,能用但折腾起来有点闹心。

先修复你的Procmail规则

你现在的规则是同时要求邮件头里有Content-Disposition:.*attachment和Content-Type:.*multipart/mixed,这俩是AND关系,必须同时满足才会触发转发,但很多带附件的邮件其实不满足这个组合:

  • 不少带附件的邮件会用multipart/alternative(比如同时有HTML和纯文本版本+附件),不是multipart/mixed
  • 还有些邮件的附件标记Content-Disposition: attachment是在子MIME部分里,而不是主邮件头里,Procmail默认只扫主邮件头,根本抓不到

给你几个调整方向:

  1. 放宽匹配条件,忽略大小写
    把规则改成这样,去掉对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
  1. 检查所有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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 11:04:36