Ubuntu 22.04 中 cron 和 systemd timer 的区别与使用

在 Ubuntu 22.04 里,cron 和 systemd timer 都能做"定时任务",但它们不是同一个东西。

  • cron:老牌、经典、直接按时间规则执行任务
  • systemd timer :systemd 原生定时机制,通常搭配 .service 使用

如果你只是想"到点执行命令",两者都可以;如果你希望和 systemd 服务管理、日志、启动顺序更好地配合,systemd timer 更现代一些。


一、cron 是什么

cron 是 Linux 里最传统的定时任务服务之一。它的特点是:

  • 语法简单
  • 适合周期性脚本
  • 使用广泛
  • 很多老系统和运维脚本都依赖它

cron 的任务通常通过 crontab 管理。

1. 查看当前用户的定时任务

bash 复制代码
crontab -l

这个命令看到的是当前用户自己的 crontab。

它对应的文件通常在:

bash 复制代码
/var/spool/cron/crontabs/<用户名>

在 Ubuntu 上,普通用户自己的 crontab 一般保存在:

bash 复制代码
/var/spool/cron/crontabs/用户名

例如 root 用户:

bash 复制代码
/var/spool/cron/crontabs/root

注意:这个文件通常不建议直接手工编辑,应该用 crontab -e。

2. 查看系统级的 cron 任务

除了用户自己的 crontab,Ubuntu 还有一些系统级任务文件,常见位置如下:

bash 复制代码
/etc/crontab
/etc/cron.d/
/etc/cron.hourly/
/etc/cron.daily/
/etc/cron.weekly/
/etc/cron.monthly/

这些地方放的是系统维护类任务,比如日志清理、数据库更新、临时文件清理等。

3. cron 的时间格式

cron 表达式一般长这样:

bash 复制代码
* * * * * command

顺序是:

text 复制代码
分 时 日 月 周

例子:每天凌晨 2 点执行一次:

bash 复制代码
0 2 * * * /usr/local/bin/backup.sh

例子:每 5 分钟执行一次:

bash 复制代码
*/5 * * * * /usr/local/bin/check.sh

二、systemd timer 是什么

systemd timer 是 systemd 提供的定时功能。它不是单独靠一行 cron 表达式来写,而是通过两个文件配合:

  • .service:真正执行什么任务
  • .timer:什么时候触发这个任务

简单理解就是:

  • service 负责"干活"
  • timer 负责"定时叫它干活"

这套方式更适合现代 Linux 服务管理。

1. 查看已有 timer

bash 复制代码
systemctl list-timers

如果输出很多,可以这样看:

bash 复制代码
systemctl list-timers | less

2. timer 的优点

  • 能和 systemd 服务统一管理
  • 日志可直接用 journalctl 看
  • 支持开机补跑、延迟启动等能力
  • 比 cron 更适合做"服务型任务"

三、cron 和 systemd timer 的区别

可以简单记成:

项目 cron systemd timer
定位 传统计划任务 systemd 原生定时器
配置方式 一行 cron 表达式 .timer + .service
管理方式 crontab -e / /etc/crontab systemctl enable --now xxx.timer
日志查看 依赖系统日志 journalctl 更直接
适合场景 简单周期任务 需要和服务联动的任务

一句话总结:

cron 更像"老式闹钟",systemd timer 更像"和系统服务联动的智能闹钟"。


四、cron 的一些常见定时任务

Ubuntu 上,cron 常见用途包括:

  • 定时备份数据库
  • 定时清理日志
  • 定时同步文件
  • 定时检查服务状态
  • 定时重启某些进程

例如每晚 3 点清理临时文件:

bash 复制代码
0 3 * * * /usr/local/bin/clean-temp.sh

例如每天凌晨 1 点备份 MySQL:

bash 复制代码
0 1 * * * /usr/local/bin/mysql-backup.sh

这些都很适合用 cron。


五、如何自定义 systemd timer

下面用一个简单例子说明:定时重启 nginx。

这很适合拿来理解 systemd timer,因为它能很直观看到"service + timer"的组合。

1. 创建 service 文件

先创建一个服务文件:

bash 复制代码
/etc/systemd/system/nginx-restart.service

内容如下:

ini 复制代码
[Unit]
Description=Restart Nginx Service

[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl restart nginx

说明:

  • Type=oneshot 表示这是一次性任务
  • ExecStart 是实际执行的命令

2. 创建 timer 文件

再创建:

bash 复制代码
/etc/systemd/system/nginx-restart.timer

内容如下:

ini 复制代码
[Unit]
Description=Run Nginx Restart Every Day at 3 AM

[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
Unit=nginx-restart.service

[Install]
WantedBy=timers.target

说明:

  • OnCalendar=*-*-* 03:00:00:每天凌晨 3 点触发
  • Persistent=true:如果机器错过了时间,开机后补跑
  • Unit=:触发哪个 service

3. 启用 timer

bash 复制代码
systemctl daemon-reload
systemctl enable --now nginx-restart.timer

4. 查看 timer 是否生效

bash 复制代码
systemctl list-timers | grep nginx-restart

5. 查看日志

如果任务执行了,可以看日志:

bash 复制代码
journalctl -u nginx-restart.service

六、用 apt 做一个定时示例

如果你想用 apt 做演示,比较合理的方式是:定时更新软件包索引,而不是随便自动升级所有东西。

比如写一个 service 执行:

bash 复制代码
apt update

service 示例

ini 复制代码
[Unit]
Description=Run apt update

[Service]
Type=oneshot
ExecStart=/usr/bin/apt update

然后配一个 timer,定时执行即可。

不过要注意:

  • apt update 可以定时跑
  • apt upgrade、apt dist-upgrade 要更谨慎
  • 自动升级系统可能影响生产环境稳定性

如果是生产机,更建议先做告警、检查、备份,再决定是否自动升级。


七、怎么选择

简单判断:

  • 任务很简单,只是按时间跑脚本 → 用 cron
  • 任务希望和 systemd 服务统一管理 → 用 systemd timer
  • 需要日志、依赖、补跑、服务联动 → 优先 systemd timer
  • 老项目、老脚本兼容 → 继续用 cron 也没问题

八、实际工作里怎么记

你可以这样理解:

  • crontab -l 看的是当前用户自己的 cron 任务
  • 用户 crontab 实际存放在 /var/spool/cron/crontabs/用户名
  • 系统级 cron 任务常放在 /etc/crontab 和 /etc/cron.d/
  • systemd timer 通过 .service + .timer 管理
  • 想定时重启 nginx、执行备份、跑检查任务,systemd timer 很顺手

九、最简结论

text 复制代码
cron = 传统定时任务
systemd timer = systemd 原生定时器
text 复制代码
crontab -l 看的是当前用户的 cron 任务,底层通常对应 /var/spool/cron/crontabs/用户名
text 复制代码
systemd timer 适合"定时触发一个服务",cron 适合"按时间执行一条命令或脚本"
相关推荐
律宏阔3 小时前
WSL Docker 端口明明空闲,但就是绑不上端口
linux·windows
律宏阔3 小时前
WSL 突然断网,无法 ping 内网或外网
linux·windows
穷人小水滴3 小时前
用容器编译 VirtualBox 虚拟机软件 (ArchLinux, podman)
linux·容器·virtualbox
乱码三千4 小时前
如何优雅地直连无公网 IP 的远程 GPU 服务器
linux·人工智能·程序员
yunwei374 小时前
使用 eBPF 跟踪 Nginx 请求
linux·后端·性能优化
yunwei374 小时前
使用 eBPF 跟踪 MySQL 查询
linux·后端·性能优化
yunwei374 小时前
eBPF 示例教程:使用 XDP 捕获 TCP 信息
linux·后端·性能优化
judezh4 小时前
api 容器一直 unhealthy?我把一个 Agent 运行时的健康检查逐条拆了,查出四个问题
运维·docker
GeW4 小时前
制造业高端化,为什么必须重估Linux和数据库?
linux
GeW4 小时前
工业场景中的Linux与数据库选型:高端化转型的技术底座
linux