2011-02-28 155 views
1

我有一個腳本用於在自定義服務器環境中重新部署幾個程序(即:不是具有代碼熱啓動的已建立的標準容器)。爲此,它會關閉服務器進程,但這需要一些時間來完全關閉所有連接。這些不是perlscript的子進程。他們通常每次運行數百天,所以我寧願不必將服務器進程封裝在perlscript中,以便我可以在幾個月或幾年之後優雅地關閉它們。Perl,等待非子進程退出

所以目前要等待他們重新部署期間死亡的,我解析的ps -ef輸出,抓住PID字段,殺死PID,等待60秒(這似乎是一個合理的時間與這些進程),重新檢查ps -ef以確保它們已經死亡等。繼續使用拷貝,chmods等。

這個解決方案對我來說感覺很蹩腳。我已經谷歌全部,並沒有看到這個特定的話題上的任何東西;有一堆關於等待分岔的孩子的材料,如果只是以這種方式運行,waitpid將是完美的。

從閱讀How to wait for exit of non-children processes(這是c具體)我猜測除了讀取/ proc/pid之外,其他方面我可以做的其他事情不多,但我想也許會有一個perl特定的解決方案某處。有任何想法嗎?

回答

4

您可以使用kill 0, $pid(成功時返回1,失敗時返回0)而不是重新檢查ps -ef,但可能會出現pid可能已被重用的問題。

如果你已經有ps解析代碼,它可能不值得它切換,但有Proc::ProcessTable

除此之外,沒有想法。

+1

其它疑難雜症是( )發送信號,即使信號爲0,也受到Unix權限的限制。因此,例如,在用戶帳戶運行的Perl腳本中執行kill(0,123),其中進程ID 123由root擁有將導致返回值爲假(0),儘管進程ID 123處於活動狀態並且好。 – 2011-02-28 01:38:11

+2

@John Siracusa:我假設他/她有權殺死,但如果沒有,您仍然可以通過測試'kill(0,$ pid)||來判斷一個進程是否存在。 $! != ESRCH' – ysth 2011-02-28 02:29:11

+0

感謝輸入的人,我很高興我沒有錯過一些明顯的'銀彈'。 'kill 0,$ pid'在檢查errno時很有效。 – Decker 2011-02-28 18:33:50

0

在Unix \ Linux中,只有父進程在進程退出父進程時纔會收到信號 - 這是操作系統功能,而不是語言特定的。

其他的解決方案將是等同於你的 - 檢查進程表的過程的存在(雖然具體的方法可能會發生變化 - 如使用PS或直接查詢內核),使用殺

+0

是的,我想也許有人在某處寫了類似java的桌面集成庫的東西,並且可以利用某種操作系統集成。謝謝您的幫助! – Decker 2011-02-28 18:36:27