2012-11-29 143 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'