跳到主內容

【除錯】【Mac】crontab 無法正常執行

在 macOS 環境下,crontab 沒執行的原因通常與 Linux 大不相同,最常見的元凶是 macOS 嚴格的隱私權與安全性限制(TCC),其次是排程時間定義環境變數路徑問題。

以下是排查 macOS Crontab 沒有執行(或執行失敗)的精準步驟:

原因一:macOS 系統權限封鎖(最常見原因)

從 macOS Mojave (10.14) 開始,系統引入了 TCC 隱私保護。cron 程式預設沒有權限讀取使用者的家目錄(如 /Users/srou/shell/...。當排程時間到了,cron 試圖去讀取腳本時,會直接被系統阻擋(Permission denied),而且這種阻擋不會寫入您的自訂 log 中。

🛠️ 解決步驟:

  1. 打開 Mac 的 「系統設定」 (System Settings)

  2. 進入 「隱私權與安全性」 (Privacy & Security) -> 「全權硬碟存取權」 (Full Disk Access)

  3. 檢查清單中是否有 cron

  4. 如果沒有(通常預設沒有):

    • 點擊下方的 「+」 號。

    • 按下 Command + Shift + G 彈出路徑輸入框。

    • 輸入 /usr/sbin/cron 並點選開啟。

  5. cron 的開關切換為開啟(允許)狀態。

原因二:Crontab 時間格式設定不符合預期

您的設定為:

*/5 * * * 1-5 /Users/AAA/shell/clean_mangodb.sh 2025-02-20
  • */5:每 5 分鐘執行一次。

  • 1-5:週一至週五(Monday to Friday)。

  • 今天是 2026 年 5 月 19 日(星期二),時間符合週一至週五。

  • 排查點:請確認您測試當下的時間是否在週一至週五。如果是週末測試,它確實不會觸發。

原因三:沒有擷取錯誤輸出,導致失敗卻看不到

目前您的 clean_mangodb.sh 這一行沒有加上錯誤重導向。如果腳本在啟動時就因為路徑或權限問題掛掉,您完全無法得知原因。

🛠️ 解決步驟:

請修改 crontab,將標準錯誤輸出(stderr)導向暫存檔:

  1. 輸入 crontab -e

  2. 將該行修改為(加上 >> /tmp/clean.log 2>&1):

    */5 * * * 1-5 /Users/AAA/shell/clean_mangodb.sh 2025-02-20 >> /tmp/clean.log 2>&1
    
  3. 儲存離開後,靜待下一個 5 分鐘,然後查看 /tmp/clean.log 的內容。

原因四:macOS cron 服務未啟動

雖然 macOS 預設會啟動 cron,但有時可能被關閉。macOS 負責管理後台服務的是 launchd

🛠️ 檢查與重啟步驟:

檢查 cron 是否在運行:

sudo launchctl list | grep cron

如果沒有輸出,或是您想強制重載 cron 服務,請執行:

# 停止服務
sudo launchctl unload /System/Library/LaunchDaemons/com.vix.cron.plist 2>/dev/null
# 重新啟動服務
sudo launchctl load /System/Library/LaunchDaemons/com.vix.cron.plist

原因五:環境變數(PATH)問題

cron 執行時的環境變數非常乾淨,通常 PATH 只有 /usr/bin:/bin

如果您的 clean_mangodb.sh 腳本內容中呼叫了某些透過 Homebrew 安裝的工具(雖然您目前主要使用 curlsed,這些在 /usr/bin 都有),但若腳本有用到 /usr/local/bin/opt/homebrew/bin 的套件,就會噴出 command not found

  • 驗證方式:透過上述原因三加上 2>&1 導出 log 後,最容易看出來是否卡在找不到指令。

📋 建議排查順序

  1. 先去 全權硬碟存取權 補上 /usr/sbin/cron 的權限(90% 是這個問題)。

  2. crontab -e 把日誌重導向 >> /tmp/clean.log 2>&1 補上。

  3. 檢查 /tmp/clean.log 的報錯訊息。