Linux 定时任务怎么选:cron、systemd timer 和一次性任务
"每天早上备份一次"这件事,Linux 上至少有三种做法。很多人条件反射写 crontab,但这不总是最优解。
这篇按场景给结论,不做无意义的全面罗列。
先说结论:四种场景怎么选
场景 | 选什么 | 理由
简单的周期性任务 | cron | 最短、最熟、无依赖
任务要等服务就绪才能跑 | systemd timer | 能声明 After= 依赖
机器可能关机,错过要补跑 | systemd timer | Persistent=true
只在某个时刻跑一次 | systemd timer(OnCalendar + 自删) 或 at | 不用记得清理
判断标准其实就一句:这个任务"错过之后要不要补"? 要补,就别用 cron。
cron 的三个坑
坑一:环境变量几乎没有
你在终端里 echo $PATH 看到的是一长串,cron 里可能只有 /usr/bin:/bin。
所以脚本里调用了装在 /usr/local/bin 下的命令,手动跑没问题,cron 跑就报"command not found"。
排查方法:在 crontab 里加一行把环境打出来。
* * * * * env > /tmp/cron-env.txt
等一分钟看那个文件,就知道 cron 到底给了你什么环境。
根治办法:脚本里一律用绝对路径,或者在 crontab 开头显式声明:
PATH=/usr/local/bin:/usr/bin:/bin
SHELL=/bin/bash
坑二:时区和你以为的不一样
cron 用的是系统时区。服务器如果是 UTC,你写的 0 3 * * * 实际是北京时间 11 点。
先确认:
timedatectl | grep "Time zone"
date
要么把系统时区改对,要么在 crontab 里写 CRON_TZ=Asia/Shanghai(部分 cron 实现支持,Debian 系可以)。
坑三:没有日志,出问题只能猜
cron 默认把输出发邮件,而大多数服务器没配邮件,于是输出直接扔进黑洞。
必须显式重定向:
0 3 * * * /path/to/job.sh >> /var/log/job.log 2>&1
注意 2>&1 不能省——很多脚本只把正常输出写文件,错误信息跑到 stderr,结果日志里一片空白,你还以为它成功了。
一个额外提醒
crontab 里 % 是特殊字符(表示换行),写在命令里会被截断。日期格式化那种 date +%Y%m%d 必须转义成 \%Y\%m\%d,或者干脆把逻辑写进脚本文件里。
systemd timer 补了什么
补上依赖关系
cron 不管你依赖的服务起没起。systemd 可以声明:
[Unit]
After=network-online.target
Wants=network-online.target
意思是"等网络真的可用了再跑",而不是"开机就跑然后失败"。
补上错过补偿
[Timer]
OnCalendar=daily
Persistent=true
Persistent=true 会在开机后检查:上次计划的时间点有没有跑过?没跑过就立刻补一次。
这个特性对家用服务器、经常重启的机器极其重要。 cron 做不到——错过了就是错过了。
补上统一日志
journalctl -u myjob.service --since "1 hour ago"
不用管日志文件在哪、有没有被切走。
一个容易踩的细节:Type 写错
systemd timer 配的 service 通常是一次性任务,必须写:
[Service]
Type=oneshot
如果误写成 Type=simple,systemd 会以为进程一直在跑(因为它不会主动退出),后续的 timer 调度就乱了——表现为"第一次跑了,后面再也不跑"。
这个坑很隐蔽,因为 systemctl status 看起来还挺正常。
相比之下 cron 的优势在哪
说了 systemd 这么多好处,但 cron 仍然有价值的场景是:
- 极简需求:一条
0 3 * * * /backup.sh就够了,没必要建两个 unit 文件 - 用户级任务:
crontab -e不需要 root,systemd 的 user unit 要开loginctl enable-linger,麻烦 - 容器内:很多精简镜像里 systemd 根本不存在,只能靠 cron 或语言的调度库
小结
记住两条判断线:
1. 错过要补吗? 要补 → systemd timer(Persistent=true)
2. 有依赖顺序吗? 有 → systemd timer(After=)
两条都不涉及,就老老实实写 cron,别为了"先进"给自己加配置负担。
工具没有高下,只有匹不匹配。
- 点赞
- 收藏
- 关注作者
评论(0)