答案是需分层抓取日志:先查系统日志确认任务是否触发,再重定向脚本输出捕获stderr错误,必要时用auditd审计进程行为,并检查邮件队列获取未重定向的失败信息。

Linux 定时任务执行失败时,仅靠常规日志往往难以定位根本原因——系统日志(如 /var/log/cron)只记录“是否触发”,不记录命令内部为何失败。要真正审计到失败细节,需分层抓取:系统调度层、进程执行层、脚本输出层。
确认 cron 是否真实触发了任务
这是第一步,排除“根本没跑”的情况:
- 查
journalctl -u cron -n 50或grep CRON /var/log/syslog(Ubuntu/Debian)或grep CRON /var/log/cron(CentOS/RHEL),找形如(root) CMD (/path/to/script.sh)的行 - 若无该记录,说明 crontab 未生效:检查
crontab -e语法、服务状态(systemctl status cron)、用户权限或 SELinux 策略拦截
捕获脚本实际执行输出与错误
系统日志不会保存 stdout 和 stderr,必须主动重定向:
- 在 crontab 条目末尾添加:
>> /var/log/myjob.log 2>&1,例如:0 * * * * /opt/bin/backup.sh >> /var/log/backup.log 2>&1 - 确保目标路径可写:
sudo chown root:adm /var/log/myjob.log && sudo chmod 644 /var/log/myjob.log - 失败线索常藏在 stderr 中:权限拒绝、命令未找到(
command not found)、路径错误、变量未定义等,这些几乎都出现在重定向日志里
用 auditd 深度审计进程行为(含失败原因)
当需要追踪“为什么脚本退出码非零”或“被 kill”等底层行为时,auditd 可记录 execve 系统调用:
- 添加规则监控 cron 启动的子进程:
sudo auditctl -a always,exit -F arch=b64 -S execve -F path=/usr/sbin/crond -k cron_spawn
(适用于 x86_64;如为 arm64,用arch=b32) - 执行任务后,检索失败事件:
sudo ausearch -k cron_spawn --raw | aureport -f -i | grep "exit=-"
其中exit=-13表示权限拒绝,exit=-2表示文件不存在 - 注意:auditd 默认不启用 cron 相关规则,且日志存于
/var/log/audit/audit.log,需确保其空间充足
检查邮件队列作为兜底线索
若未重定向输出,cron 会尝试发邮件给任务所有者(即使本地 mail 服务未配好,也会暂存在队列中):
- 查看当前用户邮件:
mail或直接读取/var/mail/$(whoami) - 常见失败提示如:
(root) MAIL (mailing output)出现在系统日志中,意味着脚本有输出但未重定向,此时邮件正文就是关键错误信息 - 若邮件无法投递,部分系统会将内容写入
/var/log/mail.err或/var/log/syslog,搜索sendmail或postfix关键词











