2011-07-18 37 views
6

我需要根據後臺進程的返回值採取一些操作,即如果它首先終止。後臺進程的返回值

具體來說:在理想的操作中,我作爲後臺進程運行的服務器將永遠持續運行。在這種情況下,將它保留在後臺是有道理的,因爲我希望我的shell腳本在產生服務器之後做其他事情。但是,如果服務器異常終止,我想最好使用服務器的退出返回值來決定是否殺死我的主腳本。如果這是不可能的,我至少要中止主腳本,而不是運行失敗的服務器。

我在尋找shell腳本異步回調的性質。一種解決方案是產生一個監視進程,定期檢查服務器是否失敗。最好我想在主外殼腳本中沒有這樣做。

回答

-2

您可以將後臺進程嵌套在腳本中。例如,如果您想發送到後臺的過程被稱爲富:

#!/bin/sh 

foo 

if [ $? ] 
then 
    # do something here if process failed 
fi 

然後只需運行上面的腳本在後臺,而不是foo。如果你需要關閉它,你可以終止它,但是否則它將永遠不會終止,只要foo繼續運行,並且如果foo死亡,則可以根據它的錯誤代碼進行任何你想做的事情。

2

當孩子通過陷阱SIGCHLD退出時,可以使用shell陷阱來調用函數。如果只有一個後臺進程正在運行,那麼您可以在sigchld處理程序中輸入wait並在那裏獲取狀態。如果有多個後臺運行的孩子會變得更復雜一些;這裏是一個代碼示例(僅用bash測試):

set -m # enable job control 
prtchld() { 
    joblist=$(jobs -l | tr "\n" "^") 
    while read -a jl -d "^"; do 
    if [ ${jl[2]} == "Exit" ] ; then 
     job=${jl[1]} 
     status=${jl[3]} 
     task=${jl[*]:4} 
     break 
    fi 
    done <<< $joblist 
    wait $job 
    echo job $task exited: $status 
} 
trap prtchld SIGCHLD 

(sleep 5 ; exit 5) & 
(sleep 1 ; exit 7) & 

echo stuff is running 

wait 
0

我喜歡第一個更適合我的目的,我認爲在「如果進程失敗,在這裏做些什麼」我可以通過使用它的名稱來殺死爲foo調用這個包裝腳本的腳本。

我認爲第一種解決方案適用於多個孩子。無論如何,我必須快速完成這項工作,所以我使用了一個適用於我的應用程序的黑客程序:

我像往常一樣在主腳本內啓動後臺進程,然後使用$!得到它的pid(因爲$!返回最後一個bg pid),睡眠2秒鐘並執行ps -e | grep pid根據(ps -e | grep pid)的返回值檢查進程是否還在。這適用於我,因爲如果我的後臺進程中止它立即(因爲地址正在使用)。