首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

Linux Crontab 定時任務配置全攻略:語法、環境變量、日誌重定向、防重複執行

     編輯:PHP 相關知識

Linux Crontab 定時任務配置全攻略:語法、環境變量、日誌重定向、防重複執行

Crontab 是 Linux 系統級定時任務調度器,廣泛用於數據庫備份、日誌清理、報表生成、緩存預熱等自動化運維場景。本文系統總結配置文件位置、命令語法、時間表達式、常見坑點(環境變量、路徑、重複執行)及最佳實踐。

一、核心文件與目錄結構

路徑用途
/etc/crontab系統級任務(需指定運行用戶),由 cron 守護進程直接讀取
/var/spool/cron/用戶級任務目錄,每用戶一個文件(如 /var/spool/cron/root)
/etc/cron.d/應用安裝包投放任務片段的目錄(同 /etc/crontab 格式)
/etc/cron.allow / /etc/cron.deny控制用戶是否允許使用 crontab 命令(allow 優先,不存在則 deny 生效)
/etc/cron.hourly/daily/weekly/monthly/系統周期性腳本目錄,由 run-parts 通過 /etc/crontab 觸發

二、crontab 命令管理

crontab -l          # 查看當前用戶任務列表
crontab -e          # 編輯當前用戶任務(打開編輯器,保存後自動生效)
crontab -r          # 刪除當前用戶所有任務(慎用!)
crontab -u user -l  # root 查看指定用戶任務
crontab /path/file  # 從文件導入任務覆蓋當前

三、任務行格式詳解(6 個字段)

* * * * *  command-to-execute
- - - - -
| | | | └─ 星期 (0-7) (0或7=星期日)
| | | └──── 月份 (1-12)
| | └────── 日期 (1-31)
| └──────── 小時 (0-23)
└────────── 分鐘 (0-59)

特殊符號

  • *:任意值(每分鐘/每小時...)
  • */n:每 n 分鐘/小時...(如 */5 * * * * 每 5 分鐘)
  • a-b:範圍(如 9-18 表示 9 點到 18 點)
  • a,b,c:離散列表(如 1,15,30 表示 1、15、30 分)

經典示例

# 每天 12:12 執行備份腳本
12 12 * * * /home/backup/daily.sh >> /home/backup/daily.log 2>&1

# 每 2 分鐘檢查服務狀態
*/2 * * * * /usr/local/bin/check_service.sh

# 工作日 23:00 執行報表生成
0 23 * * 1-5 /home/reports/generate.sh

# 每周日 19:00 發送郵件摘要
0 19 * * 0 mail -s "Weekly Report" admin@example.com < /tmp/weekly.txt

# 系統啟動後 5 分鐘執行(需 @reboot 支援)
@reboot sleep 300 && /home/scripts/startup.sh

四、重定向與日誌:/dev/null 2>&1 深度解析

# 文件描述符:0=stdin, 1=stdout, 2=stderr
# > file       : 1> file  (標準輸出重定向到文件)
# 2> file      : 錯誤輸出重定向到文件
# 2>&1         : 錯誤輸出重定向到 標準輸出(即文件描述符 1 指向的地方)
# &> file      : 1>file 2>&1 的簡寫

# 完整寫法:標準輸出和錯誤輸出都寫入日誌文件
* * * * * /path/script.sh >> /var/log/script.log 2>&1

# 完全丟棄輸出(靜默運行)
* * * * * /path/script.sh > /dev/null 2>&1

# 僅保留錯誤日誌
* * * * * /path/script.sh > /dev/null 2>> /var/log/script_error.log

注意:2>1(缺少 &)會被理解為「錯誤輸出重定向到名為 1 的文件」,而非標準輸出。

五、避坑指南:環境變量、路徑、併發

1. 環境變量缺失

Cron 運行環境極簡(無 PATH、HOME、LANG 等)。腳本內必須顯式聲明:

#!/bin/bash
# 腳本頭部聲明
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export LANG=en_US.UTF-8
# 或 source /etc/profile

2. 僅使用絕對路徑

  • 腳本路徑:/home/user/scripts/backup.sh
  • 命令路徑:/usr/bin/php、/usr/bin/mysqldump、/bin/date
  • 文件路徑:/data/backup/

3. 防止重複執行(鎖機制)

任務執行時間超過調度間隔會導致併發,造成資源爭搶、數據不一致。

# 方法一:flock 文件鎖(推薦,自動釋放)
* * * * * flock -xn /tmp/myjob.lock -c '/home/scripts/myjob.sh'

# 方法二:進程檢查(適用於無 flock 環境)
* * * * * pgrep -f 'myjob.sh' > /dev/null || /home/scripts/myjob.sh

# 方法三:腳本內部 PID 文件鎖
#!/bin/bash
LOCK="/tmp/myjob.pid"
if [ -f $LOCK ] && kill -0 $(cat $LOCK) 2>/dev/null; then
    echo "Already running" ; exit 1
fi
echo $$ > $LOCK
trap "rm -f $LOCK" EXIT
# ... 業務邏輯 ...

六、調試與故障排查

  1. 檢查 cron 守護進程:systemctl status cron 或 systemctl status crond
  2. 查看系統日誌:grep CRON /var/log/syslog(Debian/Ubuntu)或 /var/log/cron(CentOS/RHEL)
  3. 手動執行腳本驗證:/home/scripts/backup.sh 確認無語法錯誤、權限問題。
  4. 郵件通知:默認輸出會郵件發給任務擁有者。設置 MAILTO="" 禁用,或 MAILTO="admin@example.com" 指定接收郵箱(需配置 postfix/sendmail)。

七、systemd Timer 替代方案(現代 Linux 推薦)

systemd Timer 提供更精確的時間控制、依賴管理、日誌整合、隨機延遲(RandomizedDelaySec)等優勢。

# /etc/systemd/system/backup.timer
[Unit]
Description=Daily Backup Timer

[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=30m

[Install]
WantedBy=timers.target

# /etc/systemd/system/backup.service
[Unit]
Description=Daily Backup Service

[Service]
Type=oneshot
ExecStart=/home/backup/daily.sh

# 啟用
systemctl daemon-reload
systemctl enable --now backup.timer

八、參考資源

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved