1.7.6 计划任务日志与故障排查
计划任务日志与故障排查重点在于确认任务是否被调度、是否执行成功以及输出是否可追踪。排查应形成“调度记录 → 执行日志 → 运行环境 → 权限与安全”的闭环,并为关键任务显式定义日志路径与格式,便于统一检索与留存。
原理草图(日志与排查路径):
常见日志来源与定位命令(含解释):
# 1) 查看 cron 调度记录(RHEL/CentOS)
grep CRON /var/log/cron
# 2) Ubuntu/Debian 常用位置
grep CRON /var/log/syslog
# 3) systemd 定时器与服务日志
journalctl -u backup.timer --since "today"
journalctl -u backup.service -n 50 --no-pager
# 4) 用户邮件输出(若 MAILTO 生效)
sudo ls -l /var/spool/mail/
sudo tail -n 50 /var/spool/mail/$USER
# 5) 审计与 SELinux(排查权限拒绝)
sudo ausearch -m avc -ts recent
sudo grep denied /var/log/audit/audit.log | tail -n 20
标准化任务日志示例(含输出与错误重定向):
# /etc/cron.d/backup 示例:每天 02:30 执行备份
# 分 时 日 月 周 用户 命令
30 2 * * * root /usr/local/bin/backup.sh >> /var/log/backup/backup.log 2>&1
配套脚本示例(统一日志头、PATH、锁文件、超时):
#!/bin/bash
# /usr/local/bin/backup.sh
set -euo pipefail
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
LOG_DIR="/var/log/backup"
LOCK_FILE="/var/run/backup.lock"
mkdir -p "$LOG_DIR"
{
echo "==== $(date '+%F %T') host=$(hostname) task=backup ===="
# 防并发:如果已锁定则退出
exec 9>"$LOCK_FILE"
flock -n 9 || { echo "backup already running"; exit 1; }
# 执行命令(示例)
tar -czf /data/backup/$(date +%F).tar.gz /etc
echo "backup ok"
} >> "$LOG_DIR/backup.log" 2>&1
systemd 定时器示例与日志定位:
# /etc/systemd/system/backup.service
[Unit]
Description=Daily backup service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
# /etc/systemd/system/backup.timer
[Unit]
Description=Daily backup timer
[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true
[Install]
WantedBy=timers.target
# 启用并查看状态与日志
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers | grep backup
journalctl -u backup.timer -n 20
journalctl -u backup.service -n 50
典型故障与排查步骤(含命令解释):
# 1) 任务未触发:服务状态与语法校验
systemctl status crond # 确认 cron 服务是否运行
crontab -l # 查看当前用户任务
crontab -u root -l # 查看指定用户任务
# 2) 时间与时区检查
timedatectl # 时区与时间同步状态
date # 当前系统时间
# 3) 环境变量缺失导致命令找不到
env -i /bin/bash -lc '/usr/local/bin/backup.sh'
# 若此处失败,说明依赖环境变量或路径
# 4) 权限问题检查
ls -l /usr/local/bin/backup.sh
sudo -u root /usr/local/bin/backup.sh # 以任务用户手动执行
日志轮转建议(避免日志占满磁盘):
# /etc/logrotate.d/backup
/var/log/backup/*.log {
daily
rotate 7
compress
missingok
notifempty
copytruncate
}
排错案例演练(最小复现):
# 1) 创建一个每分钟写日志的测试任务
echo '* * * * * /usr/bin/date >> /var/log/cron_test.log 2>&1' | crontab -
# 2) 观察调度与输出
sleep 70
tail -n 3 /var/log/cron_test.log
grep CRON /var/log/cron | tail -n 3
练习与自检:
1. 将测试任务改为使用相对路径(如 date),观察是否执行失败并解释原因。
2. 配置一个 systemd timer,并验证 OnCalendar 与 Persistent 的行为差异。
3. 人为移除脚本执行权限,定位故障日志与修复步骤。
4. 为关键任务添加锁文件并模拟并发触发,验证锁机制效果。