定时任务:crontab, anacron, systemd-timer | Scheduled Tasks

章节概述

核心理念:定时任务是系统自动化的基石——从定期备份、日志轮转到系统维护,都依赖于精确的调度机制。理解 crontab、anacron 和 systemd timer,就像理解 C 语言的事件循环一样重要。


第1节:crontab 语法

1.1 基本语法

# crontab 格式:
# ┌───────────── 分钟 (0-59)
# │ ┌───────────── 小时 (0-23)
# │ │ ┌───────────── 日 (1-31)
# │ │ │ ┌───────────── 月 (1-12)
# │ │ │ │ ┌───────────── 星期 (0-7, 0和7都是周日)
# │ │ │ │ │
# * * * * * command

# 示例:
0 2 * * * /path/to/backup.sh          # 每天凌晨 2 点
30 8 * * 1-5 /path/to/weekday.sh      # 工作日 8:30
0 */4 * * * /path/to/every4hours.sh    # 每 4 小时
0 0 1 * * /path/to/monthly.sh          # 每月 1 号
0 22 * * 5 /path/to/friday.sh          # 每周五 22:00

1.2 crontab 操作

# 编辑当前用户的 crontab
crontab -e
 
# 查看当前用户的 crontab
crontab -l
 
# 查看所有用户的 crontab
sudo ls -la /var/spool/cron/crontabs/
 
# 删除当前用户的 crontab
crontab -r
 
# 从文件导入 crontab
crontab backup.crontab
 
# 特定用户的 crontab
sudo crontab -u username -e

1.3 crontab 特殊字符串

字符说明等价
@reboot系统启动时运行-
@yearly每年运行0 0 1 1 *
@monthly每月运行0 0 1 * *
@weekly每周运行0 0 * * 0
@daily每天运行0 0 * * *
@hourly每小时运行0 * * * *

1.4 crontab 最佳实践

# 1. 设置环境变量
PATH=/usr/local/bin:/usr/bin:/bin
MAILTO=user@example.com
SHELL=/bin/bash
 
# 2. 使用完整路径
0 2 * * * /usr/bin/python3 /home/user/script.py
 
# 3. 重定向输出
0 2 * * * /path/to/script.sh >> /var/log/script.log 2>&1
 
# 4. 使用锁防止重复执行
0 * * * * flock -n /tmp/script.lock /path/to/script.sh

第2节:anacron

2.1 anacron 概念

anacron 适用于非 24/7 运行的系统(如笔记本电脑),它会在系统启动时检查错过的任务。

# /etc/anacrontab 格式:
# period  delay  job-identifier  command
1         5      daily-backup    /usr/local/bin/backup.sh
7         10     weekly-cleanup  /usr/local/bin/cleanup.sh
字段说明
period执行间隔(天)
delay启动后延迟(分钟)
job-identifier任务标识
command要执行的命令

2.2 anacron 使用

# 手动触发 anacron
sudo anacron -f
 
# 查看 anacron 状态
sudo anacron -n
 
# 编辑 anacron 配置
sudo vim /etc/anacrontab
 
# 查看 anacron 日志
grep anacron /var/log/syslog

第3节:systemd timer

3.1 创建 systemd timer

# /etc/systemd/system/mytask.timer
[Unit]
Description=Run mytask daily
 
[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=1800
 
[Install]
WantedBy=timers.target

3.2 创建对应的服务

# /etc/systemd/system/mytask.service
[Unit]
Description=My daily task
After=network.target
 
[Service]
Type=oneshot
ExecStart=/usr/local/bin/mytask.sh
User=root
StandardOutput=journal
StandardError=journal

3.3 timer 定时选项

选项说明
OnCalendar按日历时间触发
OnBootSec启动后延迟
OnUnitActiveSec上次执行后间隔
Persistent错过的任务在启动后补执行
RandomizedDelaySec随机延迟
AccuracySec时间精度

3.4 systemd timer 操作

# 启用 timer
sudo systemctl enable mytask.timer
sudo systemctl start mytask.timer
 
# 查看 timer 状态
sudo systemctl list-timers
sudo systemctl list-timers --all
 
# 查看 timer 详情
sudo systemctl status mytask.timer
sudo systemctl cat mytask.timer
 
# 查看执行历史
sudo journalctl -u mytask.service
 
# 手动触发
sudo systemctl start mytask.service

第4节:at/batch

4.1 at 一次性任务

# 在指定时间执行任务
echo "/path/to/script.sh" | at 2:00 AM
echo "/path/to/script.sh" | at 10:00 PM tomorrow
echo "/path/to/script.sh" | at noon + 3 days
 
# 交互式创建
at now + 1 hour
# 输入命令,Ctrl+D 结束
 
# 查看任务队列
atq
 
# 删除任务
atrm <job_id>

4.2 batch 批处理

# 在系统负载低时执行
echo "/path/to/heavy_task.sh" | batch
 
# 查看 batch 队列
atq -b

第5节:日志查看

5.1 cron 日志

# 查看 cron 日志
grep CRON /var/log/syslog
grep CRON /var/log/cron
 
# 查看特定用户的 cron 日志
grep CRON | grep username
 
# 使用 journalctl 查看
sudo journalctl -u cron
sudo journalctl -u crond

5.2 systemd timer 日志

# 查看特定服务的日志
sudo journalctl -u mytask.service
 
# 查看最近的日志
sudo journalctl -u mytask.service -n 50
 
# 实时查看日志
sudo journalctl -u mytask.service -f
 
# 按时间范围查看
sudo journalctl -u mytask.service --since "2026-08-22" --until "2026-08-23"

第6节:定时任务对比

特性crontabanacronsystemd timer
适用场景服务器笔记本/桌面现代系统
最小间隔1 分钟1 天微秒级
错过任务不补执行启动后补执行可配置
依赖管理支持
日志集成syslogsyslogjournal
资源控制支持
并发控制需手动需手动内置
配置文件/etc/crontab/etc/anacrontab.timer + .service