如何查看 mailq 队列中邮件的具体内容
用 postcat -q 邮件ID 查看 Postfix 队列中邮件的完整内容;-bh 参数分别显示正文和头部。本文含批量查看所有队列邮件头部的脚本与队列目录说明。
一句话回答:如果 mailq 背后是 Postfix,用 postcat -q 邮件ID 即可查看队列中该邮件的完整内容。postcat -bh -q 邮件ID 以可读格式输出头部(-h)和正文(-b)。邮件 ID 从 mailq 输出的第一列获取(如 A705238B4C,末尾的 *、! 或部分版本中的 # 状态标记不用带)。
基本用法
mailq # 列出队列,第一列是邮件 ID
# A705238B4C* 2043 Mon Sep 29 10:00:00 sender@example.com ...
postcat -q A705238B4C # 查看完整原始内容
postcat -bh -q A705238B4C # 可读格式:头部 + 正文
postcat -h -q A705238B4C # 只看头部
postcat -b -q A705238B4C # 只看正文
注意:mailq 输出中 ID 后面跟的 *(在 active 队列)、!(被 hold)及 Postfix 3.5+ 的 #(强制过期)是状态标记,不是 ID 的一部分,复制时不要带上。
批量查看所有队列邮件的头部
以下需要支持 postqueue -j 的 Postfix(3.1+)和 jq,并需要队列读取权限。结构化输出可兼容长队列 ID,不依赖十六进制短 ID;先在少量邮件上抽查,邮件头可能包含个人信息:
postqueue -j | jq -r '.queue_id' | while IFS= read -r id; do
echo "=== $id"
postcat -h -q "$id" | grep -E '^(From|To|Subject|Date):'
echo
done
队列文件在磁盘上的位置
Postfix 队列主目录通常是 /var/spool/postfix/,实际以 postconf queue_directory 为准,相关子目录:
| 目录 | 内容 |
|---|---|
incoming |
刚进入、尚未处理的邮件 |
active |
正在投递的邮件 |
deferred |
投递失败、等待重试的邮件(堆积通常在这里) |
hold |
被人工/策略 hold 住的邮件 |
bounce |
每邮件的退信状态记录,不等同于可直接读取的退信邮件队列 |
文件可能按哈希分层存储(如 A/7/05238B4C),但日常不需要直接翻目录——postcat 就是为此存在的。
该头部筛选脚本只显示指定字段的首行,折叠头部和 MIME 编码主题仍需邮件解析工具处理;队列变化时某些 ID 可能已不存在。
配套的队列管理命令
以下不是纯查看命令:重投可能增加负载,删除邮件不可撤销。先确认队列 ID、权限和处理范围,不要频繁对故障中的全队列 flush。
mailq | tail -1 # 看队列总量("in 123 Requests")
postqueue -f # 立即重试投递全部队列邮件
postsuper -d 邮件ID # 删除指定邮件
postsuper -h 邮件ID # hold 住 / postsuper -H 解除
常见问题(FAQ)
Q:postcat -q 报错 "no such file"?
A:邮件可能刚被投递成功或过期删除了——mailq 的输出是快照,队列时刻在变。重新跑 mailq 确认 ID 还在。
Q:队列里几万封垃圾邮件怎么来的?
A:常见原因:服务器被当成开放中继、本地脚本/网站被入侵发垃圾邮件、或上游收件方拒收导致退信堆积。先看 postcat -h 里几封样本的 From/To 判断来源,清队列前先堵住源头,否则清了还会涨。
Q:deferred 队列一直涨,怎么处理?
A:先看 mailq / postqueue -j 的投递错误以及 Postfix 日志;集中保存日志时,保留队列 ID 和投递状态,再按该邮件 ID 追查重试过程。postcat 主要查看邮件内容,原始头部不保证包含延迟投递原因,常见是目标服务器拒收、DNS 解析失败或本机 IP 进了黑名单。解决根因后 postqueue -f 重投;确认无望的邮件用 postsuper -d 清理。
核查依据
本文依据官方文档核对,示例未在实际业务环境运行;上线前请按部署版本、权限与数据范围验证。