生成启停脚本
大约 4 分钟centos
概述
使用本脚本生成用于启停 java 项目的三个脚本 start.sh,stop.sh,service.sh,运行前修改下面代码中步骤1的几个变量,执行后生成三个脚本
#!/bin/bash
# ==========================================
# 🚀 Java 启停脚本生成器
# ==========================================
# 1. 基础配置区域 (每次有新项目只需修改这里)
APP_NAME="xmscomm" # 项目名称
JAR_FULL_PATH="/projs/xinmingsheng/backend/xmscommerce.jar" # JAR包绝对路径
CONFIG_FULL_PATH="/projs/xinmingsheng/backend/application.yml" # 配置文件绝对路径
OUTPUT_BIN_DIR="/projs/xinmingsheng/sh" # 生成的脚本存放目录
LOG_DIR="/var/log" # 日志存放目录
PID_DIR="/var/run" # PID存放目录
# 2. JVM 参数配置
JAVA_OPTS="-Xms512m -Xmx512m -Dspring.config.location=${CONFIG_FULL_PATH}"
# ==========================================
# 👇 以下为生成逻辑,通常不需要修改
# ==========================================
# 自动解析路径
JAR_FILE_NAME=$(basename "$JAR_FULL_PATH")
JAR_FILE_PATH=$(dirname "$JAR_FULL_PATH")
# 确保输出目录存在
mkdir -p "$OUTPUT_BIN_DIR"
echo "开始为项目 [$APP_NAME] 生成管理脚本..."
# ------------------------------------------
# 生成 start.sh
# ------------------------------------------
START_SCRIPT_PATH="$OUTPUT_BIN_DIR/start-${APP_NAME}.sh"
cat << EOF > "$START_SCRIPT_PATH"
#!/bin/bash
# 启动脚本配置 (自动生成)
APP_NAME="${APP_NAME}"
JAR_FILE_NAME="${JAR_FILE_NAME}"
JAR_FILE_PATH="${JAR_FILE_PATH}"
JAR_PATH="${JAR_FULL_PATH}"
CONFIG_FILE="${CONFIG_FULL_PATH}"
LOG_FILE="${LOG_DIR}/${APP_NAME}.log"
STARTUP_LOG="${LOG_DIR}/${APP_NAME}-startup.log"
PID_FILE="${PID_DIR}/${APP_NAME}.pid"
JAVA_OPTS="${JAVA_OPTS}"
$(cat << 'BODY'
# 检查必要文件是否存在
if [ ! -f "$JAR_PATH" ]; then
echo "$(date): 错误: 找不到 JAR 文件: $JAR_PATH" >> "$STARTUP_LOG"
exit 1
fi
if [ ! -f "$CONFIG_FILE" ]; then
echo "$(date): 警告: 找不到配置文件: $CONFIG_FILE" >> "$STARTUP_LOG"
fi
# 检查 Java 是否安装
if ! command -v java &> /dev/null; then
echo "$(date): 错误: Java 未安装" >> "$STARTUP_LOG"
exit 1
fi
# 检查是否已在运行
if [ -f "$PID_FILE" ]; then
OLD_PID=$(cat "$PID_FILE")
if ps -p "$OLD_PID" > /dev/null 2>&1; then
echo "$(date): 警告: $APP_NAME 已在运行 (PID: $OLD_PID)" >> "$STARTUP_LOG"
exit 1
else
echo "$(date): 清理陈旧的 PID 文件" >> "$STARTUP_LOG"
rm -f "$PID_FILE"
fi
fi
# 切换到项目目录
cd "$JAR_FILE_PATH" || exit 1
# 启动应用
echo "$(date): 启动 $APP_NAME 服务..." >> "$STARTUP_LOG"
nohup java $JAVA_OPTS -jar "$JAR_FILE_NAME" >> "$LOG_FILE" 2>&1 &
# 记录进程 ID
PID=$!
echo $PID > "$PID_FILE"
echo "$(date): $APP_NAME 服务启动完成,PID: $PID" >> "$STARTUP_LOG"
# 验证进程是否在运行
sleep 3
if ps -p "$PID" > /dev/null 2>&1; then
echo "$(date): 验证: 进程 $PID 正在运行" >> "$STARTUP_LOG"
else
echo "$(date): 错误: 进程 $PID 启动后立即退出" >> "$STARTUP_LOG"
rm -f "$PID_FILE"
exit 1
fi
BODY
)
EOF
echo "✅ 生成成功: $START_SCRIPT_PATH"
# ------------------------------------------
# 生成 stop.sh
# ------------------------------------------
STOP_SCRIPT_PATH="$OUTPUT_BIN_DIR/stop-${APP_NAME}.sh"
cat << EOF > "$STOP_SCRIPT_PATH"
#!/bin/bash
# 关闭脚本配置 (自动生成)
APP_NAME="${APP_NAME}"
PID_FILE="${PID_DIR}/${APP_NAME}.pid"
LOG_FILE="${LOG_DIR}/${APP_NAME}.log"
SHUTDOWN_LOG="${LOG_DIR}/${APP_NAME}-shutdown.log"
$(cat << 'BODY'
# 记录关闭开始时间
echo "$(date): 开始停止 $APP_NAME 服务..." >> "$SHUTDOWN_LOG"
# 方法1: 通过 PID 文件停止进程
if [ -f "$PID_FILE" ]; then
PID=$(cat "$PID_FILE")
if ps -p "$PID" > /dev/null 2>&1; then
echo "$(date): 通过 PID 文件找到进程 $PID,正在停止..." >> "$SHUTDOWN_LOG"
kill "$PID"
# 等待进程结束,最多30秒
TIMEOUT=30
while [ $TIMEOUT -gt 0 ] && ps -p "$PID" > /dev/null 2>&1; do
sleep 1
TIMEOUT=$((TIMEOUT-1))
done
# 如果进程还在,强制杀死
if ps -p "$PID" > /dev/null 2>&1; then
echo "$(date): 正常停止失败,强制杀死进程 $PID..." >> "$SHUTDOWN_LOG"
kill -9 "$PID"
sleep 2
fi
# 确认进程已停止
if ps -p "$PID" > /dev/null 2>&1; then
echo "$(date): 错误: 无法停止进程 $PID" >> "$SHUTDOWN_LOG"
exit 1
else
echo "$(date): 成功停止进程 $PID" >> "$SHUTDOWN_LOG"
rm -f "$PID_FILE"
fi
else
echo "$(date): 警告: PID 文件存在但进程 $PID 未运行" >> "$SHUTDOWN_LOG"
rm -f "$PID_FILE"
fi
else
echo "$(date): 警告: 未找到 PID 文件 $PID_FILE" >> "$SHUTDOWN_LOG"
fi
BODY
)
EOF
echo "✅ 生成成功: $STOP_SCRIPT_PATH"
# ------------------------------------------
# 生成 service.sh
# ------------------------------------------
SERVICE_SCRIPT_PATH="$OUTPUT_BIN_DIR/${APP_NAME}-service.sh"
cat << EOF > "$SERVICE_SCRIPT_PATH"
#!/bin/bash
# 服务管理脚本 (自动生成)
SCRIPT_DIR="\$(cd "\$(dirname "\${BASH_SOURCE[0]}")" && pwd)"
START_SCRIPT="${START_SCRIPT_PATH}"
STOP_SCRIPT="${STOP_SCRIPT_PATH}"
PID_FILE="${PID_DIR}/${APP_NAME}.pid"
APP_NAME="${APP_NAME}"
JAR_FILE_NAME="${JAR_FILE_NAME}"
$(cat << 'BODY'
case "$1" in
start)
echo "启动 $APP_NAME 服务..."
"$START_SCRIPT"
;;
stop)
echo "停止 $APP_NAME 服务..."
"$STOP_SCRIPT"
;;
restart)
echo "重启 $APP_NAME 服务..."
"$STOP_SCRIPT"
sleep 3
"$START_SCRIPT"
;;
status)
if [ -f "$PID_FILE" ]; then
PID=$(cat "$PID_FILE")
if ps -p "$PID" > /dev/null 2>&1; then
echo "$APP_NAME 正在运行 (PID: $PID)"
exit 0
else
echo "$APP_NAME PID 文件存在但进程未运行"
exit 1
fi
else
# 检查是否有通过其他方式启动的进程
PROCESSES=$(ps aux | grep "$JAR_FILE_NAME" | grep -v grep)
if [ -n "$PROCESSES" ]; then
echo "$APP_NAME 在运行但没有 PID 文件:"
echo "$PROCESSES"
exit 0
else
echo "$APP_NAME 未运行"
exit 3
fi
fi
;;
*)
echo "用法: $0 {start|stop|restart|status}"
exit 1
;;
esac
BODY
)
EOF
echo "✅ 生成成功: $SERVICE_SCRIPT_PATH"
# ------------------------------------------
# 赋予可执行权限
# ------------------------------------------
chmod +x "$START_SCRIPT_PATH" "$STOP_SCRIPT_PATH" "$SERVICE_SCRIPT_PATH"
echo "🎉 全部脚本生成完毕并已赋予执行权限!"
echo "👉 您可以使用以下命令管理服务:"
echo " $SERVICE_SCRIPT_PATH start|stop|restart|status"
然后通过命令 sudo ln -s /projs/xinmingsheng/sh/xmscomm-service.sh /usr/local/bin/xmscomm 创建服务脚本的软连接,此后可以在系统内的任意路径调用服务命令,该命令的最后 xmscomm 就是在任意路径可执行的命令,例如 xmscomm status, xmscomm start
通过命令 find / -type l -name "*barrel*" 2>/dev/null 模糊查询已经创建的软连接
命令 sudo rm /usr/local/bin/barrel-service 删除现有软连接
