创建脚本appctl.sh
#!/bin/bash
# 定义常量
CONFIG_FILE="./apps.conf"
APP_STATUS_RUNNING="已经启动!"
APP_STATUS_NOT_RUNNING="没有启动!"
# 读取配置文件
if [ ! -f "$CONFIG_FILE" ]; then
echo "配置文件 $CONFIG_FILE 不存在!"
exit 1
fi
# 解析配置文件
declare -A APP_NAMES APP_JARS APP_PARAMS APP_PORTS
while read -r line || [[ -n "$line" ]]; do
# 跳过注释和空行
if [[ $line == \#* ]] || [[ -z $line ]]; then
continue
fi
# 解析配置项
APP_NAME=$(echo "$line" | awk '{print $1}')
APP_JAR=$(echo "$line" | awk '{print $2}')
APP_PARAMS=$(echo "$line" | awk '{$1=$2=$NF=""; print $0}')
APP_PORT=$(echo "$line" | awk '{print $NF}')
# 保存到关联数组中
APP_NAMES["$APP_NAME"]=$APP_NAME
APP_JARS["$APP_NAME"]=$APP_JAR
APP_PARAMS["$APP_NAME"]=$APP_PARAMS
APP_PORTS["$APP_NAME"]=$APP_PORT
done < "$CONFIG_FILE"
# 启动指定应用程序
start() {
# 循环启动应用程序
for app_name in "${!APP_NAMES[@]}"; do
# 检查是否指定了启动该应用程序
if [ -z "$1" ] || [[ " ${1[@]} " =~ " ${app_name} " ]]; then
APP_PORT=${APP_PORTS[$app_name]}
APP_PARAMS=${APP_PARAMS[$app_name]}
APP_JAR=${APP_JARS[$app_name]}
# 检查应用程序是否已经启动
if lsof -Pi :$APP_PORT -sTCP:LISTEN -t >/dev/null ; then
echo "$app_name (端口 $APP_PORT) $APP_STATUS_RUNNING"
else
nohup java -jar "$APP_JAR" "$APP_PARAMS" >/dev/null 2>&1 &
echo "启动 $app_name (端口 $APP_PORT) ..."
fi
fi
done
}
# 关闭指定应用程序
stop() {
# 循环关闭应用程序
for app_name in "${!APP_NAMES[@]}"; do
# 检查是否指定了关闭该应用程序
if [ -z "$1" ] || [[ " ${1[@]} " =~ " ${app_name} " ]]; then
APP_PORT=${APP_PORTS[$app_name]}
# 检查应用程序是否已经启动
if lsof -Pi :$APP_PORT -sTCP:LISTEN -t >/dev/null ; then
# 关闭应用程序
PID=$(lsof -i :$APP_PORT -t)
kill -9 $PID
echo "关闭 $app_name (端口 $APP_PORT) ..."
else
echo "$app_name (端口 $APP_PORT) $APP_STATUS_NOT_RUNNING"
fi
fi
done
}
# 重启指定应用程序
restart() {
stop $1
start $1
}
# 打印帮助信息
usage() {
echo "使用方法: $0 {start|stop|restart} [应用程序1 应用程序2 ...]"
exit 1
}
# 判断命令行参数
case "$1" in
start)
start "${@:2}"
;;
stop)
stop "${@:2}"
;;
restart)
restart "${@:2}"
;;
*)
usage
;;
esac
使用方法:
./app_control.sh {start|stop|restart} [应用程序1 应用程序2 ...]
参数说明:
start
:启动指定的应用程序,如果未指定应用程序,则启动全部应用程序。stop
:停止指定的应用程序,如果未指定应用程序,则停止全部应用程序。restart
:重启指定的应用程序,如果未指定应用程序,则重启全部应用程序。[应用程序1 应用程序2 ...]
:可选参数,指定要启动/停止/重启的应用程序,多个应用程序名之间用空格分隔。
配置文件格式:
应用程序的配置信息以行为单位存储在配置文件中,每行包含四个字段,各字段之间用空格分隔:
应用程序名 应用程序JAR包路径 应用程序启动参数 应用程序监听端口
应用程序名
:任意字符串,用于标识该应用程序。应用程序JAR包路径
:该应用程序的可执行JAR包的路径。应用程序启动参数
:该应用程序启动时需要的参数,可以为空。应用程序监听端口
:该应用程序监听的端口号。
注意事项:
- 配置文件必须存在,并且必须以UTF-8编码保存。
- 配置文件中每行必须符合上述格式,且各字段之间用空格分隔。
- 如果应用程序JAR包路径中包含空格,必须使用双引号将路径括起来。
- 如果应用程序启动参数中包含空格,必须使用双引号将参数括起来。
- 如果应用程序监听端口与其他应用程序监听端口重复,可能会导致启动失败。
- 如果应用程序启动失败,可以查看应用程序日志文件(通常是当前目录下的nohup.out文件)获取更多信息。
最后,建议在运行脚本前先使用chmod +x app_control.sh
命令将脚本文件修改为可执行文件。
apps.conf
# 应用程序名称 应用程序JAR包路径 应用程序参数 端口号
myapp1 /usr/local/myapp1.jar --config=/etc/myapp1.conf 8080
myapp2 /usr/local/myapp2.jar --config=/etc/myapp2.conf 8081
myapp3 /usr/local/myapp3.jar --config=/etc/myapp3.conf 8082
使用例子
# 启动所有应用程序
./appctl.sh start
# 启动 myapp1 和 myapp2 应用程序
./appctl.sh start myapp1 myapp2
# 关闭所有应用程序
./appctl.sh stop
# 关闭 myapp2 应用程序
./appctl.sh stop myapp2
# 重启所有应用程序
./appctl.sh restart
# 重启 myapp1 和 myapp3 应用程序
./appctl.sh restart myapp1 myapp3