一、前言
上篇《Centos8一键启动多个Springboot jar包》写了在centos环境下如何快速启动多个jar包。实际使用下来还是会发现不够完美,如我想重新启动10个jar包里面的两个,我得这么写:
./start.sh restart test1.jar; ./start.sh restart test2.jar; ./start.sh restart test3.jar;
命令很冗余,我能不能简化一下呢?说干就干。
二、步骤
2.1 获取参数
我们先来了解一下下面的命令
### start.sh
#!/bin/bash
echo "$*"
echo "$@"
echo "${@:2}"
当执行命令
./start.sh start gateway auth
效果如下:
start gateway auth
start gateway auth
gateway auth
由此看得出$*
与$@
效果是类似的,而${@:2}
是获取从第二个参数开始的其他参数。
2.2 循环遍历多个参数
再来看下面一段代码
### start.sh
#!/bin/bash
while [ $# != 0 ];do
echo "第一个参数为:$1,参数个数为:$#"
shift
done
执行上面同样的命令,看看效果
第一个参数为:gateway,参数个数为:2
第一个参数为:auth,参数个数为:1
可以看出来$#
是参数个数;$1是获取第一个参数;shift是向左移动一位,也就是说每运行一次就会把最左边的参数移除。
那我们通过上面两段代码是不是可以实现对原始脚本的优化呢?
2.3 脚本改造
具体代码请看
#! /bin/bash
# 模块,注意要与启动的jar包数量相同
MODULES=(gateway auth)
# jar包路径
JAR_PATH='/app/lib'
# 日志路径
LOG_PATH='/app/logs'
start() {
#循环遍历
while [ $# != 0 ];do
local MODULE=
local time1=
local JAR_NAME=
local commandOk=0
local count=0
local ok=0
local command="$1"
for((i=0;i<${#MODULES[@]};i++))
do
MODULE=${MODULES[$i]}
JAR_NAME=$MODULE.jar
if [ "$command" == "all" ] || [ "$command" == "$MODULE" ];then
commandOk=1
count=0
PID=`ps -ef |grep $(echo $JAR_NAME | awk -F/ '{print $NF}') | grep -v grep | awk '{print $2}'`
if [ -n "$PID" ];then
echo "$MODULE:已经运行,PID=$PID"
else
exec nohup java -Xms256m -Xmx512m -Dspring.profiles.active=prod -jar $JAR_PATH/$JAR_NAME >>$LOG_PATH/$MODULE.log 2>&1 &
PID=`ps -ef |grep $(echo $JAR_NAME | awk -F/ '{print $NF}') | grep -v grep | awk '{print $2}'`
while [ -z "$PID" ]
do
if (($count == 10));then
echo "$MODULE:$(expr $count \* 10)秒内未启动,请检查!"
break
fi
count=$(($count+1))
echo "$MODULE启动中.................."
sleep 10s
PID=`ps -ef |grep $(echo $JAR_NAME | awk -F/ '{print $NF}') | grep -v grep | awk '{print $2}'`
done
ok=$(($ok+1))
time1=$(date "+%Y-%m-%d %H:%M:%S")
echo "$time1--$MODULE:启动成功,PID=$PID"
sleep 3s
fi
fi
done
if(($commandOk == 0));then
echo "第二个参数输入错误"
else
echo "............本次共启动:$ok个服务..........."
fi
shift
done
}
stop() {
#循环遍历
while [ $# != 0 ];do
local MODULE=
local JAR_NAME=
local command="$1"
local commandOk=0
local ok=0
for((i=0;i<${#MODULES[@]};i++))
do
MODULE=${MODULES[$i]}
JAR_NAME=$MODULE.jar
if [ "$command" = "all" ] || [ "$command" = "$MODULE" ];then
commandOk=1
PID=`ps -ef |grep $(echo $JAR_NAME | awk -F/ '{print $NF}') | grep -v grep | awk '{print $2}'`
if [ -n "$PID" ];then
echo "$MODULE:准备结束,PID=$PID"
kill -15 $PID
PID=`ps -ef |grep $(echo $JAR_NAME | awk -F/ '{print $NF}') | grep -v grep | awk '{print $2}'`
while [ -n "$PID" ]
do
sleep 3s
PID=`ps -ef |grep $(echo $JAR_NAME | awk -F/ '{print $NF}') | grep -v grep | awk '{print $2}'`
done
echo "$MODULE:成功结束"
ok=$(($ok+1))
else
echo "$MODULE:未运行"
fi
fi
done
if (($commandOk == 0));then
echo "第二个参数输入错误"
else
echo "............本次共停止:$ok个服务............"
fi
shift
done
}
case "$1" in
start)
start "${@:2}"
;;
stop)
stop "${@:2}"
;;
restart)
stop "${@:2}"
sleep 3s
start "${@:2}"
;;
*)
echo "第一个参数请输入:start|stop|restart"
exit 1
;;
esac
目录结构:
脚本执行命令
# 启动若干个jar
./start.sh (restart|start) gateway auth
#启动或关闭全部进程
./start.sh (restart|start|stop) all
这样的写法比原来的简便多了。