Kill

程序管理和 pkill

  • July 3, 2014

我一直在研究使用 shell 腳本的流程管理,我開始意識到確保它正確完成是多麼困難。

例如,您可以將一個程序的PID記錄到一個文件中,並在該文件wait上,並在程序退出後清理該PID文件。

例如,如果你想從一個初始化腳本中嘗試kill這個守護程序,你可能會考慮做這樣的事情:

do_stop() {
 kill $(</var/run/program.pid)
}

這顯然是行不通的。在獲取 PID 和發送終止信號之間,另一個程序可能已經死亡並取而代之。

正確的方法似乎需要在程序的父級中使用 IPC 向其子級發送終止信號。這將確保程序的 PID 沒有被另一個程序重用。

我一直在嘗試編寫我自己的盡可能正確的初始化腳本。在這種情況下,我一直在為 NRPE 寫一篇文章。不幸的是,NRPE 將自己與 init 隔離,這意味著我無法wait使用它。相反,我想出了以下解決方案:

do_stop() {
 echo "Stopping (sending SIGTERM to) nrpe"
 pkill -u nrpe || { echo >&2 "nrpe isn't running"; exit 1; }
}

使用者執行的唯一程序nrpe是 NRPE 本身,考慮到系統在我的控制之下,我認為這是一個相對健全的解決方案。

我很好奇的是pkill(如果這是正確的詞)的原子性。我假設pkill遵循以下步驟:

  1. 解析程序標準的參數後,在程序表中查找 PID。
  2. 發送SIGTERM(預設)到獲取的 PID

假設pkill -u nrpe在第 1 步中給出的 PID 為 42。在第 2 步發生之前,是否有可能nrpe’ 的程序可能會死亡,而另一個程序可能會在其位置產生?

您懷疑存在(小!)原子性問題是正確的。

無論您使用什麼方法,無論是系統標準實用程序,例如start-stop-daemon,滾動您自己的 PID 文件,pkill用於通過使用者 ID、可執行二進製文件或其他方式查詢和殺死,在查找哪個程序之間總是有一個間隔您想殺死並將該程序ID提供給kill系統呼叫以向其發送信號。

基本上,你不應該擔心它。為了遇到麻煩,以下兩種情況都必鬚髮生:

  • 目標程序在您確定其程序 ID 和您實際殺死它的時間之間死亡。
  • 新創建的程序的程序 ID 必須在同一時間間隔內碰巧循環以重用剛剛騰出的程序 ID。

這真的不太可能。

請注意,在您正在研究的特定情況下,您實際上確實有一種方法可以保護自己免受這種情況的影響。使用者執行的唯一程序是 NRPE 本身,因此如果您在發出命令之前nrpe切換到nrpe使用者(可能來自,可能) ,在極不可能的情況下,您可能會嘗試殺死屬於其他東西的可憐的無辜程序,但您不會沒有權限這樣做,它不會有任何影響。root``kill

引用自:https://unix.stackexchange.com/questions/140552