06 - 计划任务


6.1 cron 定时任务

安装与启动

sudo pacman -S cronie
sudo systemctl enable --now cronie

crontab 语法

# 格式:分 时 日 月 周 命令
# ┌─────────── 分钟 (0 - 59)
# │ ┌─────────── 小时 (0 - 23)
# │ │ ┌─────────── 日 (1 - 31)
# │ │ │ ┌─────────── 月 (1 - 12)
# │ │ │ │ ┌─────────── 星期 (0 - 7, 0或7=周日)
# │ │ │ │ │
# * * * * * command

示例

# 每天凌晨 2 点备份
0 2 * * * /usr/bin/tar -czf /backup/home-$(date +\%Y\%m\%d).tar.gz /home/
 
# 每周一 6 点更新
0 6 * * 1 /usr/bin/pacman -Syu --noconfirm
 
# 每 5 分钟检查一次
*/5 * * * * /usr/local/bin/health-check.sh
 
# 每小时
0 * * * * /usr/local/bin/hourly-task.sh
 
# 工作日 9 点到 17 点每 30 分钟
*/30 9-17 * * 1-5 /path/to/job
 
# 每年 1 月 1 日 0 点
0 0 1 1 * echo "新年快乐"

特殊字符串

字符串等价
@reboot系统启动时
@yearly0 0 1 1 *
@monthly0 0 1 * *
@weekly0 0 * * 0
@daily0 0 * * *
@hourly0 * * * *
@reboot /usr/local/bin/startup-script.sh
@daily /usr/bin/pacman -Syy

crontab 命令

crontab -e # 编辑当前用户的任务
crontab -l # 列出任务
crontab -r # 删除所有任务
crontab -u alice -e # 编辑 alice 的任务(需 root)
 
# crontab 文件位置
/var/spool/cron/username

系统级 cron

# 系统 crontab(带用户字段)
# /etc/crontab
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
 
# 分 时 日 月 周 用户 命令
0 2 * * * root /usr/bin/backup.sh
 
# /etc/cron.d/ 目录下的任务文件(格式同 /etc/crontab)
# 系统自动读取以下目录内的脚本
ls /etc/cron.hourly/
ls /etc/cron.daily/
ls /etc/cron.weekly/
ls /etc/cron.monthly/

6.2 systemd timer(现代代替 cron)

优势

  • 与 journald 集成,日志好查
  • 错过执行可补偿
  • 可设置随机延迟
  • 支持秒级精度

创建 timer

# 1. service 文件 — 定义要执行的任务
# /etc/systemd/system/mybackup.service
[Unit]
Description=Home Directory Backup
 
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
# 2. timer 文件 — 定义触发时间
# /etc/systemd/system/mybackup.timer
[Unit]
Description=Daily home backup
Requires=mybackup.service
 
[Timer]
OnCalendar=daily # 每日 0 点
Persistent=true # 错过后补偿执行
RandomizedDelaySec=300 # 随机延迟最多 5 分钟
 
[Install]
WantedBy=timers.target

时间表达式

OnCalendar=*-*-* 02:00:00 # 每天凌晨 2 点
OnCalendar=Mon *-*-* 06:00:00 # 每周一 6 点
OnCalendar=*-*-1 00:00:00 # 每月 1 日
OnCalendar=*:0/5 # 每 5 分钟
OnBootSec=30s # 开机后 30 秒
OnUnitActiveSec=1h # 上次启动后 1 小时

启用与管理

sudo systemctl daemon-reload
sudo systemctl enable --now mybackup.timer
 
# 列出所有 timer
systemctl list-timers
systemctl list-timers --all
 
# 查看具体 timer
systemctl status mybackup.timer
journalctl -u mybackup.service # 查看执行日志

6.3 cron vs systemd timer

cronsystemd timer
日志通常发邮件或手动重定向自动 journald 集成
精度分钟
随机延迟不支持支持 RandomizedDelaySec
依赖可依赖其他 unit
补偿不支持支持 Persistent=true
环境极简(可能 PATH 不全)继承 systemd 环境

6.4 知识点概要

  1. cron 每分钟执行怎么写? → * * * * * command
  2. crontab 六个字段含义? → 分 时 日 月 周 命令
  3. 怎样让任务错过时间后补执行? → systemd timer 的 Persistent=true
  4. @reboot 做什么的? → 系统启动时执行一次
  5. systemd timer 比 cron 好在哪? → 日志系统、依赖管理、秒级精度、环境隔离