Cron 是 Linux 系統級任務調度守護進程,通過 crontab 管理用戶級定時任務。本文深度解析時間表達式、環境變量陷阱、日志審計、錯誤處理與生產級部署最佳實踐,助您構建可靠、可觀測的自動化體系。
crond (systemd 服務 cron.service/crond.service),每分鐘掃描一次所有 crontab。/var/spool/cron/username (RHEL) 或 /var/spool/cron/crontabs/username (Debian)。/etc/crontab (含 USER 字段) 及 /etc/cron.d/ 目錄下文件,適用於系統服務、跨用戶任務。# 标准 5 域 (用戶 crontab)
* * * * * command
- - - - -
| | | └─ Day of Week (0-7) (Sun=0 or 7)
| | └──── Month (1-12)
| └────── Day of Month (1-31)
| └────── Hour (0-23)
└──────── Minute (0-59)
# 系統級 6 域 (/etc/crontab, /etc/cron.d/*)
* * * * * user command
└─ User field
| 符號 | 含義 | 示例 | 等效展開 |
|---|---|---|---|
* | 所有合法值 | * * * * * | 每分鐘執行 |
, | 列表分隔 | 1,15,30 | 第 1、15、30 分鐘 |
- | 範圍 | 9-17 | 9 到 17 點 |
/ | 步長 | */10 | 每 10 分鐘 (0,10,20...) |
L | 最後 (Last) | 0 0 L * * | 每月最後一天 00:00 |
W | 工作日 (Weekday) | 0 0 15W * * | 每月 15 號最近的工作日 |
# | 第 N 個星期幾 | 0 0 * * 1#2 | 每月第二個周一 |
? | 不指定 (僅 Dom/Dow 互斥時) | 0 0 1 * ? | 每月 1 號,忽略星期 |
# 每天 02:30 備份數據庫
30 2 * * * /usr/local/bin/backup_db.sh >> /var/log/backup_db.log 2>&1
# 工作日 09:00-18:00 每 30 分鐘檢查服務
*/30 9-18 * * 1-5 /usr/local/bin/check_service.sh
# 每月第一個周五 04:00 清理臨時文件
0 4 1-7 * 5 [ "$(date +\%u)" -eq 5 ] && /usr/local/bin/cleanup_tmp.sh
# 系統啟動 5 分鐘後執行 (需 @reboot 支持)
@reboot sleep 300 && /usr/local/bin/startup_check.sh
| 命令 | 功能 | 示例 |
|---|---|---|
crontab -e | 編輯當前用戶 crontab (調用 $EDITOR) | EDITOR=vim crontab -e |
crontab -l | 列出當前用戶 crontab | |
crontab -r | 刪除當前用戶 crontab (慎用,無確認) | |
crontab -u user -e | 編輯指定用戶 crontab (需 root) | sudo crontab -u www -e |
systemctl status cron | 檢查 cron 服務狀態 |
Cron 執行時 不加載用戶 Shell 配置 (.bashrc, .profile),環境極簡:
SHELL=/bin/sh
PATH=/usr/bin:/bin
HOME=/home/username
LOGNAME=username
# 無 JAVA_HOME, PYTHONPATH, 自定義 PATH 等
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOME=/home/backup
# 業務專用變量
JAVA_HOME=/usr/lib/jvm/java-11
MYSQL_PWD=secret
# 錯誤
* * * * * python3 script.py
# 正確
* * * * * /usr/bin/python3 /home/user/scripts/script.py
# 或在腳本頭部 #!/usr/bin/env python3 並確保 PATH 包含
> /var/log/script.log 2>&1
# 分离记录
* * * * * /path/to/script.sh >> /var/log/script.out.log 2>> /var/log/script.err.log
# 仅记录错误 (标准输出丢弃)
* * * * * /path/to/script.sh >/dev/null 2>> /var/log/script.err.log
# 带时间戳前缀 (需 bash)
* * * * * /bin/bash -c '/path/to/script.sh 2>&1 | while IFS= read -r line; do echo "[$(date \"+\%F \%T\")] $line"; done >> /var/log/script.log'
/var/log/script.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 0640 user user
sharedscripts
postrotate
systemctl reload rsyslog > /dev/null 2>&1 || true
endscript
}
#!/bin/bash
set -euo pipefail
trap 'echo "ERROR at line $LINENO: $BASH_COMMAND" >&2' ERR
# 關鍵步驟檢查返回碼
critical_command || { echo "Critical step failed"; exit 1; }
# 鎖機制防止並發 (flock)
exec 9>/var/lock/script.lock
flock -n 9 || { echo "Another instance running"; exit 0; }
# 系統級 cron 日志 (需啟用 cron 日志)
# /etc/rsyslog.d/cron.conf
cron.* /var/log/cron.log
# 監控腳本 (每 5 分鐘跑一次)
# 檢查關鍵任務是否在預期時間窗口內產生日志條目
grep "$(date -d '5 minutes ago' '+\%b \%d \%H:\%M')" /var/log/cron.log | grep "backup_db.sh" || alert
| 項目 | 標準 | 驗證方式 |
|---|---|---|
| 服務狀態 | systemctl is-enabled cron && systemctl is-active cron | 啟用且運行 |
| 權限最小化 | 任務以最低權限用戶運行 (非 root) | crontab -l -u appuser |
| 環境變量顯式 | crontab 文件頭聲明 SHELL, PATH, HOME, 業務變量 | crontab -l 檢查 |
| 絕對路徑 | 所有命令、腳本、配置文件使用絕對路徑 | 代碼審查 |
| 日志規範 | 統一目錄、命名、輪轉、錯誤單獨記錄 | ls /var/log/ | grep script |
| 冪等性 | 腳本可重複安全執行 (鎖、幂等操作) | 手動連續執行 2 次無異常 |
| 超時保護 | 長任務使用 timeout 或腳本內部 alarm | timeout 3600 /path/to/script.sh |
| 變更管理 | crontab 變更走 Git / 變更單 / 代碼審查 | git log /etc/cron.d/ |

systemd Timer 提供更精確的時間控制、依賴管理、日志集成 (journalctl)、隨機化延遲 (RandomizedDelaySec) 等優勢:
*/n, L, W, #)。SHELL, PATH, HOME 等環境變量。set -euo pipefail + flock 防並發 + 返回碼檢查。規範化定時任務管理,是系統穩定性與運維效率的基石之一。
Linux HTTP 流量嗅探神器 httpry 實戰:即時抓包、離線分析與進階腳本
Linux VirtualBox 安裝 Windows 8.1 報錯 0x000000C4 解決:啟用 CMPXCHG16B CPU 指令支援
CentOS 系統將 DVD 光盤配置為本地 YUM 源的標準化流程
CentOS 编译安装 Lighttpd 1.4.x 完整步骤与配置部署
Linux 多網卡綁定模式:建立 Bonding 虛擬網卡實現高可用與負載均衡
watch 指令週期性監控實戰:高亮差異、自訂間隔、常用監控場景(網路連線、HTTP、攻擊連線、目錄變化、負載)