Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學

Linux 定時任務 crontab 完整指南:從入門到避坑實戰

編輯:Linux 系統常見問題解答

核心概念

  • crond:守護進程,每分鐘檢查任務表並執行到期任務
  • crontab:任務表文件編輯工具,每用戶一份(含 root)
  • 系統級任務:/etc/crontab、/etc/cron.d/、/etc/cron.{hourly,daily,weekly,monthly}/
  • 用戶級任務:crontab -e 編輯,存放於 /var/spool/cron/

crontab 指令速查

指令功能
crontab -e編輯當前用戶任務表(自動語法檢查)
crontab -l列出當前用戶任務表
crontab -r刪除當前用戶任務表(慎用!無確認)
crontab -u user -e以 root 身分編輯指定用戶任務表
crontab -i刪除前確認(部分發行版支援)

時間表達式詳解

* * * * *  執行命令
分 時 日 月 周
欄位範圍特殊符號範例
分0-59* */n a-b a,b,c*/5 每5分
時0-23* */n a-b a,b,c2,14,22 固定三時段
日1-31* */n a-b a,b,c L WL 月最後一天
月1-12* */n a-b a,b,c1-6 上半年
周0-7 (0/7=日)* a-b a,b,c #n1-5 工作日

進階符號:L=Last(最後一天)、W=最近工作日、#n=第 n 個周幾(如 2#3=第3個周二)

經典範例庫

# 每天 02:30 備份資料庫
30 2 * * * /usr/local/bin/backup_db.sh >> /var/log/backup.log 2>&1

# 工作日 09:00-18:00 每小時檢查服務
0 9-18 * * 1-5 /usr/local/bin/check_service.sh

# 每月 1、15 號 03:00 清理臨時檔
0 3 1,15 * * find /tmp -type f -mtime +7 -delete

# 每 10 分鐘檢查一次,僅記錄錯誤
*/10 * * * * /usr/local/bin/health_check.sh 2>&1 | logger -t health

# 開機執行一次(需 @reboot 支援)
@reboot /usr/local/bin/startup_tasks.sh

# 複雜範例:每季度最後一個月的最後一個周五 23:59
59 23 28-31 3,6,9,12 * [ "$(date +\%a)" = "Fri" ] && /usr/local/bin/quarterly_report.sh

環境變量與執行上下文——避坑核心

⚠️ 核心坑點:cron 環境極度精簡

  • 無 PATH(通常僅 /usr/bin:/bin)
  • 無 HOME、LANG、SHELL(預設 /bin/sh)
  • 不讀取 .bashrc、.bash_profile、.profile
  • 工作目錄為用戶家目錄,非腳本所在目錄

最佳實踐:腳本自帶環境

#!/bin/bash
# ===== 環境自載入區 =====
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
export LANG="en_US.UTF-8"
export TZ="Asia/Taipei"
# 載入用戶環境(可選)
[[ -f "$HOME/.bashrc" ]] && source "$HOME/.bashrc"
[[ -f "$HOME/.profile" ]] && source "$HOME/.profile"
# ========================

cd /opt/myapp || exit 1
./run_task.sh >> logs/task.log 2>&1

替代方案:crontab 內直接 source

# 每 5 分鐘執行,先載入環境
*/5 * * * * source $HOME/.bashrc && /opt/myapp/run_task.sh >> $HOME/logs/task.log 2>&1

注意:source 是 bash 內建,需確保 SHELL=/bin/bash 在 crontab 開頭聲明。

輸出重導向與靜默執行

# 完全靜默(標準輸出+錯誤輸出丟棄)
* * * * * /cmd.sh >/dev/null 2>&1

# 僅記錄錯誤到系統日誌
* * * * * /cmd.sh 2>&1 | logger -t mycmd

# 同時寫入檔案與系統日誌
* * * * * /cmd.sh >> /var/log/cmd.log 2>&1

Ubuntu/Debian 特殊說明

差異點Ubuntu/DebianRHEL/CentOS
服務名稱croncrond
日誌預設無(需手動啟用)/var/log/cron
啟用日誌編輯 /etc/rsyslog.d/50-default.conf 取消註釋 cron.*,重啟 rsyslog預設啟用
用戶環境無 .bash_profile,自動讀 .bashrc兩者皆有

Ubuntu 啟用 cron 日誌

sudo sed -i 's/^#cron\.\*/cron.*/' /etc/rsyslog.d/50-default.conf
sudo systemctl restart rsyslog
# 日誌將出現在 /var/log/cron.log

系統級任務:/etc/crontab 與 /etc/cron.d/

# /etc/crontab 格式多一個「用戶」欄位
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=root

# 範例:每天 03:15 以 root 執行
15 3 * * * root /usr/local/bin/system_cleanup.sh

# /etc/cron.d/myapp 獨立文件(推薦套件安裝方式)
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin
0 * * * * appuser /opt/myapp/hourly_sync.sh

除錯檢查清單

  1. 語法檢查:crontab -l 確認格式正確
  2. 手動測試:直接在終端執行命令,確認無誤
  3. 查看日誌:
    • 系統級:grep CRON /var/log/syslog 或 /var/log/cron
    • 用戶級:journalctl -u cron -f (systemd)
  4. 常見錯誤:
    • /bin/sh: command not found → 絕對路徑或補全 PATH
    • Permission denied → 檢查腳本 chmod +x、目錄權限
    • 環境變量缺失 → 腳本開頭 export PATH=...
    • 相對路徑失效 → 腳本內 cd /abs/path

進階技巧

鎖防止並發

*/5 * * * * flock -n /tmp/mytask.lock -c '/opt/myapp/task.sh'

隨機延遲分散峰值

# 0-300 秒隨機延遲
*/10 * * * * sleep $((RANDOM \% 300)) && /opt/myapp/task.sh

條件執行

總結

crontab 看似簡單,實則坑深。掌握三大核心:時間表達式精準控制、環境變量自帶自足、輸出重導向妥善處理。生產環境建議:腳本獨立文件化、環境變量內建、Systemd Timer 替代複雜任務、統一日誌與監控告警。定期 crontab -l > ~/crontab.backup 備份任務表,讓定時任務真正成為「設定後就能安心睡覺」的自動化利器。

Copyright © Windows教程網 All Rights Reserved