2012-06-18 80 views
0

的情況如下:我有一個Java後臺程序,這應該不會終止。但是,如果發生意外錯誤,則應通過腳本重新啓動崩潰的JVM。所以我寫了一個命令,它啓動了一個後臺bash,它有一個啓動JVM的循環(所以當JVM終止時,它將會重新啓動)。殺死一個bash進程不殺bash的當前運行的進程

/bin/bash -c "while true; do java ...; done" & 

爲了能夠停止該守護進程,我想殺死這個bash的後臺進程(通過保存它在一個文件進程ID)。這是有效的,因爲背景bash不會重新啓動JVM,但仍然不會殺死當前正在運行的進程 - 所以bash似乎在它檢查kill命令之前結束它的當前命令。我想讓當前正在運行的JVM也被殺死。

因爲我不想管2倍的PID(一個爲背景bash和一個當前運行的JVM),有「力殺」的一種方式,其設計停止當前的命令? (我在殺人時找不到這樣的東西)?

+0

主機操作系統是什麼? Linux呢?你對系統有管理權限嗎? – pb2q

+0

這是Linux。我正以具有sudo權限的用戶身份執行。 – David

+0

[殺死所有子進程的最佳方法](http://stackoverflow.com/questions/392022/best-way-to-kill-all-child-processes)可能是你正在尋找的東西。 –

回答

0

爲什麼不使用cron啓動您的應用程序,並且僅管理1 PID,一個屬於你的應用程序?這樣你總是會殺死正確的過程。

強調了一點,你可以創建一個bash腳本來管理你的應用程序:開始|停止|狀態。開始時它會將java pid保存到一個文件中。然後,您可以安排一個cron作業來驗證應用程序的狀態,如果該pid不存在,請重新啓動它。

+0

除非仔細處理(在所有讀取或更新操作期間使用羣集或類似工具鎖定),並且容易發生衝突(PID表項可以重複使用),否則pidfiles往往具有競爭條件。他們主要工作,但不一定是最佳做法。 –

+0

表示同意,但由於生產環境的限制和簡單性,這是我最常用的解決方案。這也是爲什麼你得到+1 :) – Morfic

3

有一些出於這樣的目的構建流程的管理工具:runit,daemontools的,暴發戶......在SysV的inittab文件表甚至一個條目。

所有這些都將自動在關機時立即重新啓動,跟蹤所需的狀態,而不是當前的狀態(並且嘗試信號啓動或期望的關斷),管理信號輸送等

可以在陷阱信號他們bash和觸發事件,但僅處理這可以被困的子集(您不能捕獲一個KILL,例如)。更好的做法是使用內置的工具。


(由irc.freenode.org的#bash通道使用)的ProcessManagement page of the wooledge.org wiki對在bash這樣做自己的一些其他具體的建議...雖然它也表明runit,daemontools的,和他們的親屬BEST-實踐方法。

+0

+1的額外工具,因爲他有他們安裝或有特權 – Morfic

+0

我很感謝你的廣泛答案。恐怕我的解決方案對我的情況來說太重了(依賴這些工具)。 – David

+0

@David在這種情況下,我建議閱讀鏈接的wiki頁面。 (也就是說,這些工具可能已經可用 - 例如,Upstart是現代Debian,Ubuntu和Fedora中的默認初始化工具。 –

0

這不是bash的默認行爲嗎?我認爲例如zsh做了相反的事情,並沒有發送SIGHUP給所有的子進程?也許你可以嘗試這個答案,寫一個小腳本,並開始與否?

看到了這個問題:Tie the life of a process to the shell that started it

我沒有測試,但我需要在我的網絡服務器的zsh因爲我手動啓動它,然後退出我的雙CTRL-d外殼。