这两个脚本是 RuoYi(若依)框架 提供的应用启动/管理脚本 ,分别用于 Windows(.bat) 和 Linux/Mac(.sh) 系统。它们的作用是管理 Spring Boot 应用的启动、停止、重启和状态查询。
下面我逐个给你详细讲解。
一、ry.bat(Windows 批处理脚本)
1. 脚本结构概览
设置变量 → 打印菜单 → 读取用户输入 → 跳转到对应功能 → 执行
2. 逐段详解
① 设置变量
batch
set AppName=ruoyi-admin.jar
set JVM_OPTS="-Dname=%AppName% -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC"
AppName:要运行的 jar 包名称JVM_OPTS:JVM 启动参数(内存、GC、时区、内存溢出时自动 dump 等)
② 打印菜单
batch
ECHO. [1] 启动%AppName%
ECHO. [2] 关闭%AppName%
ECHO. [3] 重启%AppName%
ECHO. [4] 启动状态 %AppName%
ECHO. [5] 退 出
显示一个交互菜单,让用户选择操作。
③ 读取用户输入并跳转
batch
set /p ID=
IF "%id%"=="1" GOTO start
IF "%id%"=="2" GOTO stop
...
set /p 等待用户输入,然后根据输入跳转到对应的标签(:start、:stop 等)。
④ :start --- 启动功能
batch
:start
for /f "usebackq tokens=1-2" %%a in (`jps -l ^| findstr %AppName%`) do (
set pid=%%a
set image_name=%%b
)
if defined pid (
echo %%is running
PAUSE
)
start javaw %JVM_OPTS% -jar %AppName%
echo Start %AppName% success...
执行流程:
- 用
jps -l列出所有 Java 进程,用findstr过滤出包含ruoyi-admin.jar的进程 - 如果找到了(
pid已定义),提示正在运行并暂停 - 如果没有运行,用
start javaw后台启动 jar 包(javaw不显示命令行窗口)
⑤ :stop --- 关闭功能
batch
:stop
for /f "usebackq tokens=1-2" %%a in (`jps -l ^| findstr %AppName%`) do (
set pid=%%a
set image_name=%%b
)
if not defined pid (
echo process %AppName% does not exists
) else (
taskkill /f /pid %pid%
)
- 查找进程
- 如果存在,用
taskkill /f /pid强制杀死 进程(/f是强制结束)
⑥ :restart --- 重启功能
batch
:restart
call :stop
call :start
先调用关闭,再调用启动。
⑦ :status --- 状态查询
batch
:status
for /f ... (查找进程)
if not defined pid (echo process is dead) else (echo is running)
3. Windows 脚本的局限性
| 问题 | 说明 |
|---|---|
jps 依赖 JDK |
需要 JDK 的 jps 命令在 PATH 中,否则找不到进程 |
taskkill /f 强制杀死 |
不会给应用优雅关闭的机会(可能造成数据不一致) |
| 交互式菜单 | 需要手动选择,不适合自动化部署(如 CI/CD) |
二、ry.sh(Linux/Mac Shell 脚本)
1. 脚本结构概览
arduino
设置变量 → 判断参数 → 定义函数 → case 匹配参数 → 执行对应函数
2. 逐段详解
① 设置变量
bash
AppName=ruoyi-admin.jar
JVM_OPTS="-Dname=$AppName -Duser.timezone=Asia/Shanghai ..."
APP_HOME=`pwd`
LOG_PATH=$APP_HOME/logs/$AppName.log
比 Windows 版本多了 APP_HOME(当前目录)和 LOG_PATH(日志路径),但注意脚本中实际把日志重定向到了 /dev/null(丢弃),所以 LOG_PATH 变量并未使用。
② 参数校验
bash
if [ "$1" = "" ]; then
echo "未输入操作名 {start|stop|restart|status}"
exit 1
fi
必须带参数运行(如 ./ry.sh start),否则提示并退出。
③ start() 函数
bash
function start()
{
PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'`
if [ x"$PID" != x"" ]; then
echo "$AppName is running..."
else
nohup java $JVM_OPTS -jar $AppName > /dev/null 2>&1 &
echo "Start $AppName success..."
fi
}
ps -ef | grep ...查找 Java 进程中包含AppName的进程号(PID)- 如果已经运行则提示,否则用
nohup ... &后台启动 > /dev/null 2>&1将标准输出和错误输出都丢弃(不写日志文件)
④ stop() 函数(优雅关闭)
bash
function stop()
{
PID=""
query(){ PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'`; }
query
if [ x"$PID" != x"" ]; then
kill -TERM $PID # 发送 SIGTERM 信号,让应用优雅关闭
echo "$AppName (pid:$PID) exiting..."
while [ x"$PID" != x"" ] # 循环等待进程真正退出
do
sleep 1
query
done
echo "$AppName exited."
else
echo "$AppName already stopped."
fi
}
这是和 Windows 版本最大的区别:
- Linux 用
kill -TERM发送终止信号,Spring Boot 会收到信号后执行优雅关闭(@PreDestroy、ShutdownHook等) - Windows 用
taskkill /f是强制杀死,不会触发优雅关闭
⑤ restart() 和 status()
bash
function restart() { stop; sleep 2; start; }
function status() { ... wc -l ... } # 统计进程数判断是否运行
⑥ case 匹配
bash
case $1 in
start) start;;
stop) stop;;
restart) restart;;
status) status;;
*) ;; # 其他参数不处理
esac
三、两个脚本的对比总结
| 维度 | ry.bat (Windows) | ry.sh (Linux/Mac) |
|---|---|---|
| 交互方式 | 菜单选择(数字) | 命令行参数(start/stop) |
| 启动方式 | start javaw |
nohup ... & |
| 关闭方式 | taskkill /f 强制杀死 |
kill -TERM 优雅关闭 |
| 进程检测 | `jps -l | findstr` |
| 日志处理 | 默认输出到控制台 | 丢弃到 /dev/null |
| 适用场景 | 本地开发测试 | 生产/测试服务器部署 |
四、使用示例
Windows(双击 ry.bat 或命令行运行)
cmd
ry.bat
# 显示菜单,输入 1 启动,2 关闭,3 重启,4 查看状态,5 退出
Linux/Mac
bash
./ry.sh start # 启动
./ry.sh stop # 停止(优雅关闭)
./ry.sh restart # 重启
./ry.sh status # 查看状态
五、脚本可以改进的地方
| 问题 | 改进建议 |
|---|---|
| 日志被丢弃(ry.sh) | 把 > /dev/null 改成 >> $LOG_PATH 保存日志 |
| Windows 强制杀进程 | 可以用 taskkill /pid(不加 /f)尝试优雅关闭 |
| 没有 PID 文件 | 可以增加 PID 文件管理,避免 ps/grep 误判 |
| 重复代码 | :start 和 :status 都在查进程,可以抽取成公共函数 |
这两个脚本是典型的 Spring Boot 应用管理脚本,在中小型项目中很常见。如果你需要更专业的部署管理,可以考虑用 systemd (Linux)、Windows Service 或 Docker/K8s。😊