2012-11-29 147 views
1

我寫了一個bash腳本,啓動了許多不同的小部件(各種Rails應用程序)並在後臺運行它們。我現在正在嘗試編寫一個恭維停止腳本來殺死啓動腳本啓動的每個進程,但我不確定如何處理它。Bash啓動和停止腳本

以下是我的啓動腳本:

#!/bin/bash 

widgets=(widget1 widget2 widget3) # Specifies, in order, which widgets to load 
port=3000 
basePath=$("pwd") 

for dir in "${widgets[@]}" 
do 
    cd ${basePath}/widgets/$dir 
    echo "Starting ${dir} widget." 
    rails s -p$port & 
    port=$((port+1)) 
done 

如果可能的話,我試圖避免保存的PID爲.pid文件,因爲他們是可怕的不可靠。有沒有更好的方法來解決這個問題?

+0

有許多強大,易用,成熟的預先存在的工具這一點;我個人永遠使用:https://github.com/nodejitsu/forever – jrajav

+1

@Kiyura是對的;有關這類事情的工具。想起「Bluepill」。你使用'.pid'文件發現什麼不可靠? – Faiz

+0

@Faiz如果一個進程意外結束,PID文件不會被清理。 – senfo

回答

0

爲了最大限度地保持額外的依賴關係,並確保我沒有關閉不屬於我的rails實例,我最終選擇了以下內容:

啓動腳本

#!/bin/bash 

widgets=(widget1 widget2 widget3) # Specifies, in order, which widgets to load 
port=3000 
basePath=$("pwd") 
pidFile="${basePath}/pids.pid" 

if [ -f $pidFile ]; 
then 
    echo "$pidFile already exists. Stop the process before attempting to start." 
else 
    echo -n "" > $pidFile 

    for dir in "${widgets[@]}" 
    do 
    cd ${basePath}/widgets/$dir 
    echo "Starting ${dir} widget." 
    rails s -p$port & 
    echo -n "$! " >> $pidFile 
    port=$((port+1)) 
    done 
fi 

停止腳本

#!/bin/bash 

pidFile='pids.pid' 

if [ -f $pidFile ]; 
then 
    pids=`cat ${pidFile}` 

    for pid in "${pids[@]}" 
    do 
    kill $pid 
    done 

    rm $pidFile 
else 
    echo "Process file wasn't found. Aborting..." 
fi 
2

一種可能性是使用pkill與在手冊頁這樣描述了-f開關:

-f  The pattern is normally only matched against the process name. When -f is set, the full command line is used. 

因此,如果你想殺死rails s -p3002,你可以進行如下操作:

pkill -f 'rails s -p3002'