一、前言
上篇《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
这样的写法比原来的简便多了。