引言
「每天凌晨备份」「每 5 分钟拉一次数据」「每周日清理日志」——这些自动化靠定时任务。Linux 有四个工具:cron(经典定时器)、anacron(补跑错过的任务)、at(一次性任务)、systemd timer(现代方案)。本文先讲透 crontab 的时间语法(最常见的坑就在格式上),再逐一拆四个工具各自的场景,最后落到环境变量、权限安全与实战(日志清理/定时备份)。
前置:/linux-shell-scripting/(任务脚本编写)。定时任务调的是脚本;脚本语言见该文。服务化任务见 /linux-systemd-services/。
目录
- 1. 定时任务全景:四种工具各司其职
- 2. crontab 配置与常用命令
- 3. crontab 时间语法详解
- 4. anacron:补跑错过的任务
- 5. at:一次性任务
- 6. systemd timer:更现代的方式
- 7. 环境变量与执行问题
- 8. 安全与权限控制
- 9. 实战:日志清理与定时备份
- 10. 速查表
- 延伸阅读
1. 定时任务全景:四种工具各司其职
定时任务 = 「时间条件 + 要执行的命令」,四种工具按「时机」分工:
| 工具 | 适用时机 | 特点 |
|---|---|---|
| cron | 周期性任务(每天/每周) | 关机期间错过的不补跑 |
| anacron | 非 7×24 开机的桌面/笔记本 | 错过的补跑 |
| at | 一次性任务(今晚 3 点) | 单次执行 |
| systemd timer | 现代服务场景 | 精准、可依赖、可日志 |
心智:服务器 7×24 用 cron;笔记本/桌面用 anacron 补跑;只跑一次用 at;跟 systemd 服务绑定的用 timer。按「错过怎么办 + 周期 + 服务化」选工具。
2. crontab 配置与常用命令
crontab 是每个用户的定时任务表:
crontab -e # 编辑当前用户的任务表(推荐)
crontab -l # 查看当前任务表
crontab -r # 删除任务表(慎用)
crontab -u root -l # 查看 root 的任务表
# /etc/crontab 系统级任务表(格式多一个用户字段)
# /etc/cron.d/ 目录放系统任务片段
# /etc/cron.hourly|daily|weekly|monthly/ 放按周期的脚本(配 run-parts)
记忆:用户任务用
crontab -e编辑,系统任务用 /etc/crontab 与 /etc/cron.d。crontab -e 会自动校验格式(写错会提示),比直接改文件安全。
3. crontab 时间语法详解
crontab 五段式时间:分 时 日 月 周:
分 时 日 月 周 命令
* * * * * /path/to/script
│ │ │ │ │
│ │ │ │ └─ 周(0-7,0/7=周日)
│ │ │ └──── 月(1-12)
│ │ └─────── 日(1-31)
│ └────────── 时(0-23)
└───────────── 分(0-59)
常见写法速查:
# 每分钟
* * * * * cmd
# 每 5 分钟
*/5 * * * * cmd
# 每天凌晨 3 点
0 3 * * * cmd
# 每周一凌晨 3 点
0 3 * * 1 cmd
# 每月 1 号 3 点
0 3 1 * * cmd
# 每天 8-18 点的每 2 小时
0 8-18/2 * * * cmd
# 多个取值:周一和周五
0 3 * * 1,5 cmd
铁律:五段顺序是「分 时 日 月 周」——最容易犯的错是把「时」写到第一位。写完
crontab -l复查一眼,前两格是不是「分 时」。「周」里 0 和 7 都是周日,别写成 6(那是周六)。
4. anacron:补跑错过的任务
anacron 解决「关机错过任务」——笔记本/桌面当天没开机,开机后补跑:
# 语法:周期(天) 延迟(分) 任务标识 命令
1 15 cron.daily run-parts /etc/cron.daily
7 30 cron.weekly run-parts /etc/cron.weekly
30 60 cron.monthly run-parts /etc/cron.monthly
anacron 补跑逻辑:
任务上次执行时间 > 周期 → 开机后延迟 N 分钟执行
例:weekly 任务 3 天没开机 → 开机后 30 分钟补跑
心法:cron 看「现在到没到时间」,anacron 看「上次跑过没有」。服务器永远开机用 cron 就够;个人电脑关机频繁,把
cron.daily这类交给 anacron 才不会「一周没跑备份」。
5. at:一次性任务
at 是一次性定时任务——「今晚 3 点跑一次」:
sudo apt install at # Debian 系装 at
sudo systemctl enable --now atd
echo "backup.sh" | at 03:00 today # 今晚 3 点
echo "cmd" | at now + 5 minutes # 5 分钟后
echo "cmd" | at 22:00 2026-10-01 # 指定日期
atq # 查看等待队列
atrm <id> # 删除某任务
记忆:at = 「echo 命令 | at 时间」——把命令通过管道交给 atd 守护进程。一次性任务别用 cron(cron 是周期的),at 用完即走、队列可查。
6. systemd timer:更现代的方式
systemd timer 是 cron 的现代替代——与服务绑定、可日志、可精准校准:
# 1. 定义任务脚本服务
sudo tee /etc/systemd/system/backup.service > /dev/null <<'EOF'
[Unit]
Description=Daily backup
[Service]
Type=oneshot
ExecStart=/opt/scripts/backup.sh
EOF
# 2. 定义定时器
sudo tee /etc/systemd/system/backup.timer > /dev/null <<'EOF'
[Unit]
Description=Run backup daily
[Timer]
OnCalendar=daily
Persistent=true # 错过的补跑(类似 anacron)
[Install]
WantedBy=timers.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers # 查看所有定时器与下次运行时间
| 对比 | cron | systemd timer |
|---|---|---|
| 依赖管理 | 无 | 可依赖其他服务 |
| 日志 | 需重定向 | journald 自动记录 |
| 错过补跑 | 否 | Persistent=true |
| 精度 | 分钟级 | 可秒级 + 随机延迟 |
心法:新服务器优先用 systemd timer——日志自动进 journald、可声明依赖、
Persistent=true补跑。cron 的优势是「人人都会、简单直接」,老环境沿用 cron 完全没问题。
7. 环境变量与执行问题
定时任务的环境变量是「空壳」——cron 不加载 shell 登录环境:
# 经典坑:cron 里找不到命令/脚本
0 3 * * * backup.sh # 找不到 backup.sh(PATH 不完整)
# 正确写法:用绝对路径 + 显式设置环境
0 3 * * * /opt/scripts/backup.sh
# 在 crontab 里设置环境变量(写在顶部)
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
0 3 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1
记忆:定时任务三大坑 = 非绝对路径、PATH 不全、输出没重定向。脚本内路径全写绝对、输出
>> log 2>&1——「任务没跑」先查日志,「跑了没效果」先查 PATH。
8. 安全与权限控制
定时任务也是攻击面——被写进恶意 cron 的服务器不少:
# 限制谁能用 crontab(/etc/cron.allow 存在时仅白名单可用)
echo "root" >> /etc/cron.allow
echo "backupuser" >> /etc/cron.allow
# 有 cron.allow 则只有列出的用户可建任务
# 检查现有任务(安全审计必做)
crontab -l
# 对 root:
crontab -u root -l
ls -la /etc/cron.d /etc/cron.daily
心法:入侵者常在 cron 里留「挖矿/后门」任务——安全巡检必看
/etc/cron.d、/etc/cron.daily、各用户 crontab(见 /linux-security-hardening/)。用cron.allow白名单锁住谁能建任务。
9. 实战:日志清理与定时备份
两个最常见场景(配合 /linux-backup-disaster-recovery/):
# 场景一:每天清理 7 天前的临时文件
# /etc/cron.daily/cleanup
#!/bin/bash
find /tmp/app -type f -mtime +7 -delete
# 场景二:每天凌晨 3 点备份数据库
# crontab -e 里加:
0 3 * * * /opt/scripts/db_backup.sh >> /var/log/db_backup.log 2>&1
# db_backup.sh 内容
#!/bin/bash
mysqldump --all-databases > /backup/db_$(date +%F).sql
find /backup -name "*.sql" -mtime +30 -delete # 只留 30 天
# 验证任务真的跑了
grep backup /var/log/syslog # cron 执行记录
# 或看自定义输出日志
tail /var/log/db_backup.log
记忆:定时任务落地三件事 = 脚本绝对路径 + 输出重定向 + 事后验证日志。脚本本身要有「幂等 + 清理旧数据」思维(备份任务一定带「保留 N 天」),否则磁盘被备份撑爆。
10. 速查表
| 需求 | 工具 | 写法 |
|---|---|---|
| 周期性任务 | cron | 0 3 * * * cmd |
| 错过补跑 | anacron | 周期+延迟(开机补) |
| 一次性任务 | at | echo "cmd" | at 03:00 |
| 服务化定时 | systemd timer | OnCalendar + Persistent |
| 每 5 分钟 | cron | */5 * * * * |
| 每周一 3 点 | cron | 0 3 * * 1 |
| 查看任务 | crontab | crontab -l |
| 限制用户 | cron.allow | 白名单文件 |
| 看执行记录 | syslog/journald | grep cron /var/log/syslog |
一句话记忆:周期用 cron(分 时 日 月 周)、错过补跑用 anacron、一次用 at、服务化用 systemd timer——时间语法是五段式「分时日月周」,排错先看 PATH 与日志。
延伸阅读
- /linux-shell-scripting/ — 任务脚本编写基础
- /linux-systemd-services/ — systemd 服务与 timer 配合
- /linux-backup-disaster-recovery/ — 备份任务实战
- /linux-logrotate-rsyslog/ — 日志轮转(清理任务另一面)
- /linux-security-hardening/ — cron 后门审计
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。