5.6.1 任务调度基础:cron/at/anacron

任务调度基础:cron/at/anacron#

1) cron:周期性计划任务#

  • 适用场景:固定周期执行(分钟/小时/天/周/月)。
  • 工作原理草图
文章图片
  • 安装/启用(不同发行版其一即可):
# RHEL/CentOS/Rocky
sudo yum install -y cronie
sudo systemctl enable --now crond

# Debian/Ubuntu
sudo apt-get update
sudo apt-get install -y cron
sudo systemctl enable --now cron
  • 配置方式
  • 用户级:crontab -e 编辑;crontab -l 查看;crontab -r 删除。
  • 系统级:/etc/crontab/etc/cron.d//etc/cron.{hourly,daily,weekly,monthly}/
  • 时间格式
分 时 日 月 周 命令
*  *  *  *  *  /path/to/cmd
  • 完整示例(含日志、环境变量、锁)
# 1) 准备脚本
sudo tee /usr/local/bin/backup.sh >/dev/null <<'EOF'
#!/bin/bash
set -e
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
TS=$(date +%F_%H%M%S)
tar -czf /data/backup/etc_${TS}.tar.gz /etc
EOF
sudo chmod +x /usr/local/bin/backup.sh

# 2) 编辑用户级 crontab
crontab -e
# 每天 02:30 备份,避免并发,用 flock 加锁;输出重定向到日志
30 2 * * * /usr/bin/flock -n /tmp/backup.lock /usr/local/bin/backup.sh >>/var/log/backup.log 2>&1
  • 命令解释
  • flock -n /tmp/backup.lock:非阻塞加锁,防止重复并发执行。
  • >>/var/log/backup.log 2>&1:标准输出与错误输出汇总到日志。
  • 排错要点
  • 检查服务:systemctl status crondsystemctl status cron
  • 检查语法:crontab -l
  • 查看日志:grep CRON /var/log/cron(RHEL系),或 journalctl -u cron
  • 常见问题:路径未写绝对路径、脚本无执行权限、环境变量缺失。

2) at:一次性计划任务#

  • 适用场景:临时、一次性任务(如维护窗口操作)。
  • 工作原理草图
文章图片
  • 安装/启用
# RHEL/CentOS/Rocky
sudo yum install -y at
sudo systemctl enable --now atd

# Debian/Ubuntu
sudo apt-get install -y at
sudo systemctl enable --now atd
  • 基本用法
# 23:00 执行一次清理
at 23:00
/usr/local/bin/cleanup.sh
<Ctrl+D>   # 结束输入
  • 管道示例
echo "/usr/local/bin/cleanup.sh >>/var/log/cleanup.log 2>&1" | at now + 10 minutes
  • 查看与删除任务
atq            # 列出任务队列
atrm 5         # 删除任务ID为5的任务
  • 权限控制
  • /etc/at.allow 允许列表;若存在仅允许其中用户。
  • /etc/at.deny 拒绝列表。
  • 排错要点
  • systemctl status atd 确认服务运行
  • journalctl -u atd 查看执行记录与错误

3) anacron:非连续运行系统的补偿调度#

  • 适用场景:偶尔关机的服务器/桌面,确保“错过的周期任务”补跑。
  • 工作原理草图
文章图片
  • 安装/启用(多数发行版随 cron 包附带):
# RHEL/CentOS/Rocky
sudo yum install -y cronie-anacron

# Debian/Ubuntu
sudo apt-get install -y anacron
  • 配置文件/etc/anacrontab
# 周期(天) 延迟(分钟) 任务名   命令
1          5           daily   /usr/local/bin/daily.sh
7          10          weekly  /usr/local/bin/weekly.sh
30         15          monthly /usr/local/bin/monthly.sh
  • 示例脚本
sudo tee /usr/local/bin/daily.sh >/dev/null <<'EOF'
#!/bin/bash
echo "$(date) daily task ok" >>/var/log/anacron_daily.log
EOF
sudo chmod +x /usr/local/bin/daily.sh
  • 排错要点
  • 查看时间戳:ls -l /var/spool/anacron/
  • 手动触发测试:sudo anacron -n -f -s(跳过时间检查立即执行)

4) 三者对比与选型#

特性 cron at anacron
任务类型 周期性 一次性 周期性补偿
精确时间 低(延迟执行)
适用系统 长时间运行 任意 非 7×24
典型场景 监控、备份 临时操作 断电补跑

5) 运维实践建议(含示例)#

  • 统一脚本路径与日志规范
# 约定:脚本放 /usr/local/bin,日志放 /var/log/jobs
sudo mkdir -p /var/log/jobs
  • 状态检测与告警(示例:返回码检查)
#!/bin/bash
/usr/local/bin/backup.sh
if [ $? -ne 0 ]; then
  echo "backup failed at $(date)" | mail -s "cron alert" ops@example.com
fi
  • 幂等与锁(防重复执行):
/usr/bin/flock -n /tmp/collect.lock /usr/local/bin/collect.sh
  • 高频任务错峰:将 */1 拆成不同分钟偏移,避免资源峰值。

6) 练习题#

  1. 编写一个脚本 /usr/local/bin/sysinfo.sh,输出主机名、负载、磁盘使用率到 /var/log/jobs/sysinfo.log,并用 cron 每 10 分钟执行一次。
  2. 使用 at 创建一个 30 分钟后执行的任务,输出当前时间到 /var/log/jobs/at_time.log,然后查看并删除该任务。
  3. 配置 anacron 每 7 天执行一次 /usr/local/bin/weekly.sh,并手动强制触发测试执行。
  4. 故意将脚本权限去掉,观察 cron 日志错误信息并修复。