在 Linux 系統中利用 crontab 排程執行腳本修改資料庫日期,原本以為設定完成即可自動生效,卻發現隔天資料庫日期毫無變化。本文記錄完整的問題重現、排查過程、最終解決方案,以及遺留的兩個核心疑問,供遇到類似情況的系統管理員參考。
yz(一般用戶)0 1 * * * chg_date > /home/yz/yz.log(每天凌晨 1 點執行)crontab -e,以 :wq 存檔離開。| 預期 | 實際 |
|---|---|
| 隔天資料庫日期自動更新 | 資料庫日期維持前一天,chg_date 完全未執行 |
根據常見文獻說明:crontab -e 存檔後會寫入 /var/spool/cron/username,crond 守護進程每分鐘掃描 /etc/crontab、/etc/cron.d/、/var/spool/cron/ 變化並自動載入,**無需重啟服務****。因此當時未做進一步測試直接下班。
隔天發現失效後,修改 crontab 為每 2 分鐘執行一次:
*/2 * * * * chg_date > /home/yz/yz.log
等待數分鐘,資料庫日期仍未更新。隨後嘗試重啟 cron 服務:
/etc/rc.d/init.d/crond restart
結果:依然無效。
同事建議嘗試以 root 身分設定排程,並透過 su 切換用戶執行:
# root 執行 crontab -e */2 * * * * (su - yz -c "chg_date" 2>> /home/yz/yz.log)
等待數分鐘,**仍無變化**。
抱著試試看心態,再次手動執行:
/etc/rc.d/init.d/crond restart
幾分鐘後,**資料庫日期終於成功更新**,問題解決。
/var/spool/cron/yz 確實存在對應定義。/var/spool/cron/yz 檔案存在且內容正確,權限為 600,擁有者為 yz。crond 日誌(/var/log/cron)無任何錯誤訊息,亦無執行紀錄。crontab -e 存檔即刻生效,無需重啟。本環境是否存在特殊配置(如 SELinux 策略、cron.allow/deny 限制、pam 模組設定)導致 inotify 監聽失效?systemctl status crond # 或 service crond status tail -f /var/log/cron # 觀察是否有 RELOAD 或錯誤訊息
strace -p $(pidof crond) -e trace=inotify_add_watch,inotify_rm_watch
cat /etc/cron.allow # 若存在,僅名單內用戶可用 crontab cat /etc/cron.deny # 若存在,名單內用戶被禁止 # 若兩者皆不存在,預設所有用戶可用
ls -Z /var/spool/cron/yz # 確認 context 為 system_cron_spool_t restorecon -v /var/spool/cron/yz # 修復 context
# yz 用戶 crontab 寫入 */2 * * * * /bin/date >> /home/yz/test_cron.log # 觀察是否產生日誌
systemctl reload crond 或 service crond reload,確保配置立即生效,避免依賴自動重載機制。/usr/local/bin/chg_date),並重導向 stdout 與 stderr 至日誌檔便於事後追蹤。/etc/cron.d/ 目錄下獨立檔案,由 root 統一維護,避免用戶級 crontab 權限與環境變數陷阱。