我编写了一个bash脚本,它启动了许多不同的小部件(各种Rails应用程序)并在后台运行它们。我现在正在尝试编写一个赞美停止脚本来杀死该启动脚本启动的每个进程,但我不确定最好的方法来处理它。
以下是我的开始脚本:
#!/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 :(得分: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'
答案 1 :(得分: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