我编写了一个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文件中,因为它们非常不可靠。有没有更好的方法来解决这个问题?
一种可能性是将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'
为了尽量减少额外的依赖关系,并确保我不会关闭不属于我的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