前言¶
定時任務的問題往往不是跑失敗,而是不跑了也沒人知道:crontab 整行被註釋掉、launchd 的日誌路徑失效、任務退出碼長期爲 1。這些都要等幾天後發現數據沒更新,纔回頭追查。DSH 的理念是「一切皆插件」,本機巡檢也可以做成一個插件。下面介紹 feely0208/dsh-cron-guard(發佈名 @deepwhale-cn/dsh-cron-guard),它把「本機這些定時任務到底還在不在跑」變成一次體檢。
這是什麼¶
由 feely0208 維護的 DSH 插件,定位是只讀的定時任務守衛:掃描本機 launchd 與 cron 任務,判斷哪些已經悄悄停擺、哪些根本沒有留下運行證據。它不改 crontab、不寫 plist、不重啓任務、不聯網、不上傳數據。作者在 README 中明確把「不裝會怎樣」作爲開篇:整條 crontab 被註釋、日誌路徑失效、退出碼一直爲 1,都要等數據不更新才發現。
掃描範圍¶
一次掃完以下位置:
~/Library/LaunchAgents/Library/LaunchAgents- 用戶 crontab
- Linux 下額外盡力讀
/etc/crontab和/etc/cron.d/*
怎麼判「在不在跑」¶
這是本插件的設計核心。README 的結論是:launchd 的 runs(累計運行次數)和 last exit code 纔算「跑沒跑」;日誌 mtime 只證明「有沒有留下證據」。
具體分兩層:
1、對 launchd,通過 launchctl print gui/<uid>/<label> 讀 runs / last exit code / job state;連續兩次掃描 runs 不漲、且超過 N 個計劃週期沒有成功,纔算停擺。
2、如果腳本被設計成「今日已發完就靜默 exit 0」,日誌會長期不更新,不會再被誤判成停擺。
3、不寫日誌的任務可以配心跳文件,每次被觸發覆蓋寫一行時間戳,心跳新鮮即算成功。
cron 沒有 runs 可看,就按日誌判斷。
輸出哪些證據¶
每個任務會給出:上次運行、上次成功、距上次成功多久、上次退出碼、連續失敗次數、日誌尾部。日誌尾部會自動脫敏 token、郵箱、口令。
插件還會識別幾類真實坑:
#OLD-這類被註釋掉的任務- plist 缺
RunAtLoad/StartInterval/StartCalendarInterval/WatchPaths,導致永遠不自動運行 - 日誌文件不存在或 0 字節(等於沒留下證據)
Disabled=true- 空 plist 佔位
三檔結論與退出碼¶
判定結果分四檔,文本、--json、--md 三種輸出:
| 檔 | 情況 |
|---|---|
| 紅(停擺) | launchd runs 不漲且超過 N 個週期沒成功;cron 按日誌判斷;#OLD- 註釋任務;沒有任何觸發條件 |
| 黃(沒證據 / 有失敗) | 日誌文件不存在或 0 字節;上次退出碼非 0;未加載、Disabled=true、空 plist;一次性任務日期已過但從未跑 |
| 灰(一次性) | StartCalendarInterval 帶 Year / 具體日期的一次性任務,日期已過且已跑過;只是說明,不用處理 |
| 通過 | 其餘;輸出裏會帶「判活依據」(runs / 退出碼) |
退出碼:0 爲正常、1 爲有紅、2 爲只有黃。可以直接接進 CI 或巡檢腳本。
安裝與啓用¶
在 DSH 中安裝:
dsh plugin --profile web add @deepwhale-cn/dsh-cron-guard
裝好後,側欄會出現「定時任務守衛」面板,列表顯示紅/黃任務、「多久沒成功」,並可切換閾值(2/3/5 個週期)。
CLI 也可以單獨跑,不需要裝進宿主,要求 Node ≥ 18:
node bin/cli.mjs # 掃本機真實任務
node bin/cli.mjs --json # 給腳本用
node bin/cli.mjs --periods 3 --list
node bin/cli.mjs --help
配置項¶
配置文件 .cron-guard.json 按 cwd → ~ 順序查找,也可以用 --config 指定:
{
"periods": 2,
"heartbeats": {
"com.example.job": "~/path/job.last"
},
"successRe": "成功|RUN_OK",
"failRe": "失敗|error"
}
命令行等價寫法:--heartbeat com.example.job=~/path/job.last(可重複)、--periods 3。
runs 快照默認寫在 ~/Library/Application Support/dsh-cron-guard/state.json,只存 label + runs + 時間,不含任何業務數據;可以用 --no-state 關掉、用 DSH_CRON_GUARD_STATE 改路徑。
測試與安全¶
跑測試:
bash tests/run.sh
測試只在 mktemp 目錄裏造 fixture(假 HOME + 假 crontab + 假 launchctl 輸出),不讀真實 crontab、不聯網。
適用場景與注意¶
適合在本機跑 launchd / cron 定時任務、希望及早發現「靜默停擺」的開發和運維場景。插件的掃描、判定都以當前 dsh 進程權限爲準,能看到多少任務取決於運行身份;安裝前應先檢查源碼與許可證(倉庫標註爲 MIT)再決定要不要用。
結尾¶
dsh-cron-guard 補上的不是「任務怎麼配」,而是「配好的任務還在不在跑」。目錄頁與源碼見:
- 目錄頁:https://www.skillhub.cn/plugins/feely0208/dsh-cron-guard
- GitHub:https://github.com/feely0208/dsh-cron-guard