/var/spool/mail 目录大小异常增长能暴露静默异常定时任务,因为 crond 默认将任务的 stdout/stderr 发送给所属用户;若邮件服务未运行、邮箱文件缺失或权限错误,输出会堆积成 dead.letter 或持续膨胀 spool,表明存在高频未抑制输出的任务。

直接看 /var/spool/mail 目录大小变化,是排查“静默异常定时任务”的有效手段——尤其当 cron 任务频繁执行却未显式报错,但持续向 root 或其他用户发送输出时,邮件会不断堆积在 spool 中,最终生成大量 dead.letter 或撑满磁盘。
为什么 mail spool 大小能暴露隐蔽问题
crond 默认将每个任务的标准输出(stdout)和标准错误(stderr)汇总后,通过本地邮件系统发给任务所属用户(如 root)。若该用户没有启用邮件服务(如 postfix/sendmail 未运行),或对应邮箱文件(如 /var/spool/mail/root)被误删、权限异常、或磁盘满导致写入失败,系统就会退而生成 dead.letter 文件(通常落在用户家目录下)。更常见的是:邮件服务虽运行,但无人读取,spool 文件持续增长——这本身就是“有任务在高频输出”的铁证。
快速检查 spool 状态的命令组合
-
查当前邮件文件大小:
du -sh /var/spool/mail/* 2>/dev/null | sort -h—— 关注 root、daemon、nobody 等系统账户是否异常偏大 -
查 dead.letter 存在情况:
find /root /var/spool/mail -name "dead.letter" -ls 2>/dev/null—— 若存在且持续更新,说明邮件投递失败已成常态 -
查最近新增/变大的文件:
find /var/spool/mail -type f -mtime -7 -ls 2>/dev/null | sort -k7,7nr—— 找出近一周内膨胀最猛的邮箱 -
查邮件队列积压:
mailq或postqueue -p(需 postfix)—— 若显示大量 deferred 邮件,说明输出正被持续产生但无法投递
定位源头:从 spool 反推可疑 crontab
一旦发现某个邮箱(如 /var/spool/mail/root)体积异常,下一步不是清空它,而是追溯谁在往里塞内容:
-
检查所有用户的 crontab:
for u in $(cut -d: -f1 /etc/passwd); do echo "== $u =="; crontab -u "$u" -l 2>/dev/null | grep -E "(curl|wget|python|sh|echo|print)"; done | grep -A2 -B2 "*/"—— 重点找分钟级(*/1、*/5)、带输出重定向缺失、或无/dev/null抑制的命令 -
检查系统级 crontab:
grep -v "^#" /etc/crontab /etc/cron.d/* 2>/dev/null | grep -E "([[:space:]]+[^[:space:]]+){5,}.*[^&]$" | grep -v ">/dev/null"—— 过滤掉注释和后台静默任务,抓出可能输出到终端的行 -
验证某任务是否真在输出:临时在可疑行末尾加
> /tmp/cron-debug.log 2>&1,等几分钟后检查该日志是否有内容 —— 若有,就是它
确认后该怎么做
找到问题任务后,不要直接删,先治理输出:
- 对调试类输出,改用日志文件并加轮转:
> /var/log/myjob.log 2>&1+ logrotate 配置 - 对无需保留的输出,显式丢弃:
> /dev/null 2>&1 - 若确实需要邮件通知,确保只在异常时触发:
2>&1 | grep -q "ERROR" && mail -s "Alert" admin@example.com - 全局禁用默认邮件(谨慎):
echo 'MAILTO=""' >> /etc/crontab,再让关键任务按需调用mailx
spool 目录就像系统的“沉默哨兵”——它不报错,但体积会说话。定期扫一眼,比等磁盘报警后再排查,省力十倍。











