傳統 cron 雖普及,但缺乏依賴管理、日誌整合、隨機延遲、持久化儲存。systemd Timer 提供:
RandomizedDelaySec、Persistent=true (開機補跑)# 使用者 crontab
crontab -e
# 格式: 分 時 日 月 週 命令
0 2 * * * /backup.sh >> /var/log/backup.log 2>&1
*/15 * * * * /check_service.sh
# 系統 crontab (/etc/crontab) 含 USER 欄位
0 3 * * * root /scripts/daily_cleanup.sh
# 目錄式 (run-parts)
/etc/cron.d/ # 系統排程檔
/etc/cron.hourly/ # 每小時
/etc/cron.daily/ # 每天 (anacron 驅動)
/etc/cron.weekly/
/etc/cron.monthly/
/etc/systemd/system/backup.service
[Unit]
Description=Daily Backup Script
Documentation=man:backup(1)
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
User=backup
Group=backup
# 資源限制
MemoryMax=500M
CPUQuota=50%
# 環境
Environment=BACKUP_DEST=/mnt/backup
Environment=RETENTION_DAYS=30
# 日誌標籤
SyslogIdentifier=backup-script
[Install]
WantedBy=multi-user.target
/etc/systemd/system/backup.timer
[Unit]
Description=Run backup daily at 02:00 with random delay
Requires=backup.service
[Timer]
# Calendar 事件 (相對/絕對時間)
OnCalendar=*-*-* 02:00:00
# 或單調時間
# OnBootSec=15min
# OnUnitActiveSec=1d
# 關鍵現代化參數
RandomizedDelaySec=30m # 0-30 分鐘隨機延遲,避免驚群
Persistent=true # 開機時若錯過上次排程,立即執行
AccuracySec=1m # 時間精度 (預設 1min)
[Install]
WantedBy=timers.target
systemctl daemon-reload
systemctl enable --now backup.timer
# 查看狀態
systemctl list-timers --all
systemctl status backup.timer
journalctl -u backup.service -f
# 手動觸發
systemctl start backup.service
# 暫停/恢復
systemctl stop backup.timer
systemctl start backup.timer
| 表達式 | 含義 |
|---|---|
*-*-* 02:00:00 | 每天 02:00 |
Mon *-*-* 03:00:00 | 每週一 03:00 |
*-*-01 04:00:00 | 每月 1 號 04:00 |
*-01,07-01 05:00:00 | 1 月與 7 月 1 號 05:00 |
Sat,Sun *-*-* 06:00:00 | 週六日 06:00 |
*:0/15 | 每 15 分鐘 |
daily | 每天 00:00 (內建別名) |
weekly | 每週一 00:00 |
monthly | 每月 1 號 00:00 |
# 驗證表達式
systemd-analyze calendar "Mon *-*-* 03:00:00"
# 輸出下次觸發時間、間隔、經過時間
單一單元合併 (Type=oneshot + Timer 整合):簡單腳本可用 systemd-run 臨時排程:
# 一次性 10 分鐘後執行
systemd-run --on-active=10min /scripts/once.sh
# 每小時執行,隨機延遲 5 分鐘
systemd-run --on-calendar="*:0/60" --property=RandomizedDelaySec=5m /scripts/hourly.sh
多服務依賴鏈:
[Unit]
Description=Data Pipeline
After=extract.service transform.service
Requires=extract.service transform.service
[Service]
Type=oneshot
ExecStart=/scripts/load.sh
[Install]
WantedBy=multi-user.target
# Timer 只掛在最後一環
# load.timer → load.service → (Requires) transform.service → extract.service
Transient Timer (動態建立,不寫檔):
systemd-run --unit=myjob --on-calendar="*-*-* 03:00" --property=RandomizedDelaySec=1h /scripts/dynamic.sh
筆記本/桌機非持續開機,anacron 讀取 /etc/anacrontab:
# 期間(天) 延遲(分) 識別名 命令
1 5 cron.daily run-parts /etc/cron.daily
7 10 cron.weekly run-parts /etc/cron.weekly
30 15 cron.monthly run-parts /etc/cron.monthly
# systemd 內建替代
# /etc/systemd/system/cron-daily.timer
[Timer]
OnCalendar=daily
RandomizedDelaySec=1h
Persistent=true
useradd -r -s /sbin/nologin backup,最小權限set -euo pipefail、鎖檔防重入 (flock)、超時控制 (timeout)、錯誤通知 (mail/curl webhook)StandardOutput=journal + journalctl --vacuum-time=30d,或導向檔案 + logrotatesystemctl is-failed backup.service 整合 Prometheus node_exporter systemd_unit_failed 指標/etc/systemd/system/*.timer 納入 Git/Ansible/Saltsystemd-analyze verify backup.service backup.timer、systemd-dry-run| Cron 特性 | systemd Timer 對應 | 遷移步驟 |
|---|---|---|
| 使用者 crontab | 使用者級 systemd (systemd --user) | loginctl enable-linger user; 放入 ~/.config/systemd/user/ |
| MAILTO 郵件通知 | OnFailure=notify.service + sendmail/curl | 建立通知服務單元 |
| @reboot | WantedBy=multi-user.target + Type=oneshot | 服務設定 After=network-online.target |
| 環境變數 | Environment= / EnvironmentFile= | 服務單元宣告 |
| 隨機延遲 | RandomizedDelaySec | 直接設定 |
| 錯過補跑 | Persistent=true | 直接設定 |
| 並發控制 | Type=oneshot + flock / systemd-run --property=LockPersonality=... | 服務單元加鎖 |
# Timer 未觸發
systemctl list-timers --all | grep backup
systemctl status backup.timer
journalctl -u backup.timer -S -1h
# 服務失敗
journalctl -u backup.service -b
systemctl cat backup.service
# 時間表達式錯誤
systemd-analyze calendar "OnCalendar string"
# 權限問題
systemctl cat backup.service | grep User
sudo -u backup /usr/local/bin/backup.sh # 手動測試
結論:新系統預設用 systemd Timer,舊系統 Cron 共存無害。Timer 提供企業級可觀測性、可靠性、可維護性,是基礎設施即代碼的原生選擇。