Ubuntu 运维系列 | 第 15 天:定时任务与自动化——cron、systemd timer 与脚本化运维

定时任务与自动化是 Linux 运维中最能体现”效率”的两个字。一名合格的 Ubuntu 运维工程师,绝不会在每天凌晨三点手动登录服务器执行数据库备份,也不会逐台机器重复敲相同的命令。借助系统自带的 cron 与 systemd timer,配合 Shell 脚本,我们可以把周期性的巡检、备份、日志清理、监控上报等工作交给系统自动完成,从而把精力聚焦在更复杂、更有价值的问题上。本文将从 cron 的基础语法讲起,逐步深入到 systemd timer 的高级用法,最后通过一个完整的脚本化运维案例,帮你构建属于自己的自动化体系。

Ubuntu 运维 第15天

一、核心概念:cron 是什么

cron 是 Linux 系统中历史最悠久、使用最广泛的定时任务调度器,它由两部分组成:一个是常驻后台的守护进程 crond,负责每分钟醒来检查一次任务表;另一个是任务配置文件 crontab,用来声明”什么时间执行什么命令”。

在 Ubuntu 中,cron 的配置文件分散在多个位置:

  • 用户级任务表:crontab -e 编辑,实际存放在 /var/spool/cron/crontabs/ 目录下;
  • 系统级任务表:/etc/crontab 以及 /etc/cron.d/ 目录;
  • 周期目录:/etc/cron.hourly/etc/cron.daily/etc/cron.weekly/etc/cron.monthly,把脚本放入这些目录即可按对应周期自动执行。

一条 cron 时间表达式由 5 个字段组成,从左到右依次是:分、时、日、月、星期。其取值范围和常见符号如下:

字段 取值范围 常用符号
分钟 0-59 * , - /
小时 0-23 * , - /
日期 1-31 * , - /
月份 1-12 * , - /
星期 0-7(0 和 7 都代表周日) * , - /

理解这些符号是编写定时任务的第一步:* 表示任意值,, 表示枚举,- 表示范围,/ 表示步长。例如 */5 * * * * 表示每 5 分钟执行一次,0 3 * * * 表示每天凌晨 3 点整执行。

二、cron 实战:编写与调试定时任务

2.1 编辑用户级 crontab

使用 crontab -e 可以编辑当前用户的定时任务。第一次使用时会提示选择编辑器,建议选择 nano 或 vim。下面是一个典型示例,每天凌晨 3 点执行数据库备份脚本:

# 查看当前用户的定时任务
crontab -l

# 编辑定时任务
crontab -e

# 每天凌晨 3 点执行备份脚本
0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

2.2 管理 cron 服务

Ubuntu 使用 systemd 管理 cron 服务,常用命令如下:

# 查看 cron 服务状态
systemctl status cron

# 启动 / 停止 / 重启 cron 服务
sudo systemctl start cron
sudo systemctl stop cron
sudo systemctl restart cron

# 查看 cron 日志,排查任务是否正常执行
grep CRON /var/log/syslog | tail -20

2.3 一个实用的备份定时任务示例

# 编写备份脚本
cat > /usr/local/bin/backup.sh <<'EOF'
#!/bin/bash
DATE=$(date +%Y%m%d)
tar -czf /backup/www-$DATE.tar.gz /var/www/html
find /backup -name "*.tar.gz" -mtime +7 -delete
EOF

chmod +x /usr/local/bin/backup.sh

这个脚本每天打包 /var/www/html 目录,并自动清理 7 天前的旧备份,实现了备份的自动化与空间治理。

三、systemd timer:更强大的定时调度

虽然 cron 简单易用,但它存在一些局限:无法感知服务依赖、失败后不能自动重试、时间精度到分钟为止。systemd timer 作为 cron 的现代替代方案,拥有更丰富的特性,是 Ubuntu 官方推荐的新一代定时调度方式。

3.1 timer 的工作原理

一个完整的 systemd 定时任务由两个 unit 文件组成:

  • 服务单元(.service):定义要执行的具体动作;
  • 定时器单元(.timer):定义何时触发该服务。

下面是一个每天凌晨 2 点运行数据库备份的示例,先创建服务单元:

# /etc/systemd/system/db-backup.service
[Unit]
Description=Database backup service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/db-backup.sh
User=root

再创建定时器单元:

# /etc/systemd/system/db-backup.timer
[Unit]
Description=Run database backup daily at 2am

[Timer]
OnCalendar=daily
OnCalendar=*-*-* 02:00:00
Persistent=true

[Install]
WantedBy=timers.target

3.2 启用并查看 timer

# 重新加载 systemd 配置
sudo systemctl daemon-reload

# 启用并启动定时器
sudo systemctl enable --now db-backup.timer

# 查看所有定时器及其下次触发时间
systemctl list-timers --all

# 查看某个定时器的详细状态
systemctl status db-backup.timer

OnCalendar 的语法比 cron 更直观,支持 hourlydailyweeklymonthly 等关键词,也可以用 Mon..Fri*-*-1,15 等表达式表达复杂周期。Persistent=true 表示如果系统在触发时刻处于关机状态,则开机后补执行一次,这是 cron 所不具备的能力。

四、脚本化运维:把一切串起来

定时任务的价值最终要落到脚本上。一个规范的运维脚本应该具备日志记录、错误处理、幂等性等特征。下面是一个综合示例,把磁盘巡检、日志清理与告警上报整合到一个脚本中:

#!/bin/bash
# 每日巡检脚本:磁盘、内存、日志清理
LOG=/var/log/daily-check.log
echo "===== $(date '+%F %T') 巡检开始 =====" >> $LOG

# 1. 磁盘使用率检查,超过 80% 告警
DISK=$(df / | awk 'NR==2 {print $5}' | tr -d '%')
if [ "$DISK" -gt 80 ]; then
    echo "[告警] 根分区使用率 ${DISK}%" >> $LOG
fi

# 2. 清理 30 天前的旧日志
find /var/log -name "*.log" -mtime +30 -delete
echo "日志清理完成" >> $LOG

# 3. 内存使用情况记录
free -h >> $LOG
echo "===== 巡检结束 =====" >> $LOG

将这个脚本放入 /etc/cron.daily/ 目录,或为其创建对应的 systemd timer,即可实现全自动的每日巡检。进一步,你还可以在脚本中调用 Webhook,把巡检结果推送到企业微信或钉钉,构建完整的告警闭环。

五、常见问题与排查

1. cron 任务不执行怎么办?

按以下顺序排查:先用 systemctl status cron 确认服务正在运行;再检查 crontab 中命令是否写了绝对路径(cron 的环境变量非常精简,不会加载 .bashrc);最后用 grep CRON /var/log/syslog 查看执行记录,并在命令末尾加 >> /var/log/xxx.log 2>&1 重定向输出以便定位错误。

2. cron 与 systemd timer 如何选择?

简单的一次性周期任务用 cron 更省事;需要依赖其他服务、需要开机补跑、需要更精细时间控制或失败重试的场景,优先选 systemd timer。

3. 定时任务里的命令找不到?

因为 cron 的 PATH 默认只有 /usr/bin:/bin,务必在脚本里写全命令的绝对路径,或在脚本开头显式设置 PATH

4. 如何临时暂停某个定时任务?

cron 可以在对应行前加 # 注释;systemd timer 用 sudo systemctl stop xxx.timer 即可暂停,start 恢复。

总结

本文系统梳理了 Ubuntu 上定时任务与自动化的两大支柱:cron 与 systemd timer。cron 以简洁的时间表达式和庞大的历史生态见长,适合绝大多数周期任务;systemd timer 则凭借依赖管理、持久化补跑、秒级精度等特性,成为更现代化的选择。无论选用哪种,核心思路都是一致的——把重复性工作脚本化,把脚本调度交给系统,把告警与结果反馈打通。掌握这些能力后,你离”无人值守”的自动化运维又近了一大步。

下期预告:第 16 天我们将进入《Shell 脚本编程——从基础语法到运维自动化脚本》,系统讲解变量、条件判断、循环、函数等核心语法,并带你写出真正可复用的运维自动化脚本,敬请期待。

微信二维码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片快捷回复

    暂无评论内容