問:
我有乙個 python 指令碼,它將檢查佇列並對每個元素執行操作:
# checkqueue.py
while true:
check_queue()
do_something()
如何編寫 bash 指令碼來檢查它是否正在執行,如果沒有,請啟動它。 大致如下:偽**(或者它應該做類似 ps |。grep的事情? )
# keepalivescript.sh
if processidfile exists:
if processid is running:
exit, all ok
run checkqueue.py
write processid to processidfile
我將從 crontab 呼叫它
# crontab
5 * /path/to/keepalivescript.sh
乙個:避免使用 pid 檔案、cron 或任何其他試圖評估不屬於其子程序的程序。
在 Unix 中,等待子程序是有充分理由的。 任何試圖解決這個問題的方法(ps 解析、pgrep、儲存 pid 等)都是有缺陷的,並且存在漏洞。 稍後分析。
假設您的程序名為 proca,程序監控名為 procb,您需要 procb 作為 proca 的父程序。 因為只有啟動流程的流程才能可靠地等待它結束。 這在 bash 中很容易實現。
until proca; do
echo "proca crashed with exit code $?restart..." >&2
sleep 1
done
上面的 bash 在 until 迴圈中執行 proca。 第一行開始 proca 並等待它結束。 當它結束時,直到檢查其退出狀態。 如果退出狀態為 0,則表示它正常結束(這意味著您要求它以某種方式關閉,並且它成功關閉)。 在這種情況下,我們不想重新啟動它(我們只是要求它關閉! 如果退出狀態不是 0,則迴圈體將執行,這會在 stderr 上發出錯誤訊息,並在 1 秒後重新啟動迴圈(返回第 1 行)。
我們為什麼要等一會兒? 因為如果 Proca 的啟動順序出現問題並立即崩潰,您將獲得乙個非常密集的不斷重啟和崩潰的迴圈。 睡眠 1 消除了這種壓力。
然後需要做的就是啟動這個 bash 指令碼,它將監控 proca 並在必要時重新啟動它。 如果你想在引導時啟動監控指令碼(作業系統),你可以用@reboot規則在使用者的 cron(1) 中排程它。 使用 crontab -e 命令開啟 cron 規則並新增規則以啟動監視指令碼:
@reboot /usr/local/bin/procamonitor
至於不使用pid檔案的原因:
1.PID 重用(這可能導致殺死錯誤的程序)。
2.PID 檔案已過時。 您需要過於複雜的邏輯來檢查 pid 檔案是否過時,並且任何此類邏輯在 1 中都存在相同的缺陷。
3.如果您甚至沒有寫入許可權或處於唯讀環境中,該怎麼辦?
或者,檢視 systemdunit(5)。您可以將名為 proca. 的檔案新增到 lib systemd 系統目錄服務,讓 systemd 程序監控您的 proca。
[unit]
description=daemon for proca.
service]
execstart=/path/to/proca
restart=on-failure
restartsec=1s
install]
wantedby=multi-user.target
然後執行以下命令:
systemctl daemon-reload
systemctl enable proca.service
參考:stackoverflow 問題 696839
man systemd.unit
man systemctl
相關閱讀:SH 和 Bash 的區別。
2>&1 在 shell 中是什麼意思。
在 bash 中,是否更推薦使用雙括號而不是單方括號。
如何檢查是否在 bash 中設定了變數。