在Linux环境中,让系统自动执行周期性工作是运维与开发的基本功。不论是每日日志切割、每周数据库备份,还是每十分钟检查服务存活,都可以通过系统级定时机制实现。当前主流发行版主要提供两套方案:传统的crontab守护进程与较新的systemd timer。它们底层原理不同,适用场景也有区别,理解清楚才能少踩坑。

一、crontab的工作原理与基础配置
cron是Linux早期就存在的守护进程,它会读取用户级和系统级的任务表,按分钟粒度扫描时间字段并拉起对应命令。用户任务存储在/var/spool/cron/crontabs/目录下,由crontab命令编辑,而不是直接修改文件。每次保存后,cron自动重新加载,不需要重启服务。这种设计让普通用户也能安全添加任务,而不必触碰系统全局配置。
时间字段由五个位置组成:分、时、日、月、周。比如0 2 * * *表示每天凌晨两点整执行。星号代表任意值,逗号分隔多个取值,斜杠表示步长。初学者常误以为cron会继承用户登录时的环境变量,其实它只提供极简的PATH和SHELL,所以脚本里最好写绝对路径,或在任务头先source环境文件。下面是一段典型用户任务配置:
# 每天凌晨3点备份网站目录,记录日志 0 3 * * * /bin/bash /home/user/backup.sh >> /home/user/backup.log 2>&1 # 每十分钟同步一次时间 */10 * * * * /usr/sbin/ntpdate -u pool.ntp.org >/dev/null 2>&1
使用crontab -e进入编辑,保存退出即生效;crontab -l可列出当前任务,crontab -r则清空全部。需要注意,某些容器环境默认没装cron,需手动安装并启动cron或crond服务。另外,当机器关机时错过的任务不会补跑,这对必须执行的操作是隐患。
二、systemd timer的现代用法与优势
systemd timer是随systemd引入的定时单元,它配合service单元工作,把“什么时候跑”和“跑什么”拆成两个文件。timer单元定义触发条件,service单元定义执行内容。相比cron,它的最大好处是任务失败可由systemd自动重试,执行日志统一进入journald,用journalctl就能查,不再需要自己重定向输出。
timer支持多种触发器,例如OnCalendar=写类cron时间,OnBootSec=定义开机后多久跑,OnUnitActiveSec=表示上次跑完多久再跑。还能用Persistent=true让关机期间错过的任务在开机后补执行。以下示例展示一个每天四点跑的备份服务:
# /etc/systemd/system/backup.timer [Unit] Description=Daily backup timer [Timer] OnCalendar=*-*-* 04:00:00 Persistent=true Unit=backup.service [Install] WantedBy=timers.target
# /etc/systemd/system/backup.service [Unit] Description=Run backup script [Service] Type=oneshot ExecStart=/usr/bin/bash /opt/backup.sh Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
启用时执行systemctl enable --now backup.timer,之后用systemctl list-timers观察下次触发时间。由于service单元可以声明依赖、资源限制,复杂任务比cron更易管控。不过它配置文件略多,对只跑一条命令的简单需求显得重了一些。
三、如何选择与常见排错思路
面对具体需求,若只是单机简单循环命令,crontab上手更快,文档丰富且跨发行版一致。若任务要求失败通知、开机补跑、精确到秒或与服务生命周期绑定,systemd timer更合适。在混合环境中,也可以让timer调用同一个脚本,逐步迁移。关键是把脚本自身写健壮,比如前置锁文件防止重叠运行。
排错时,cron任务不跑先看/var/log/syslog或/var/log/cron有无记录;手动用对应用户执行一次命令确认权限。timer不触发则systemctl status backup.timer看是否loaded,journalctl -u backup.service查执行报错。环境变量缺失是两类方案的通病,统一在脚本里显式导出PATH、HOME能省去大量调试时间。最后提醒,修改系统级任务后,cron无需重启但timer需systemctl daemon-reload。
无论选哪种,都建议把任务输出重定向到日志或接入集中采集,避免磁盘被撑满或错误被沉默。定时任务上线前,可先设为一分钟间隔观察一轮再改正式周期,这样能快速暴露路径与权限问题,不至于等一天才发现脚本根本没动。
crontabsystemd_timerLinux定时任务修改时间:2026-08-14 22:00:34