Bash启停脚本如何正确获取Java进程PID并写入pid文件?
问题原因
你当前脚本存在两个核心问题:
$$变量获取的是当前执行脚本的Bash进程PID,不是后续启动的Java进程PID- 你用括号包裹执行的
mvn exec:java命令运行在子Shell中,父Shell无法直接获取子Shell内启动的进程ID
修正后的脚本
#!/bin/bash # 统一配置路径,避免相对路径问题 PID_FILE="/var/script/myprogram/test.pid" WORK_DIR="/var/script/myprogram/test" case $1 in start) # 先判断是否已经运行 if [ -f "$PID_FILE" ]; then echo "程序已经在运行,PID为$(cat $PID_FILE)" exit 1 fi # 切换到工作目录,不需要子Shell cd "$WORK_DIR" || exit 1 # 后台启动Java进程,&符号放到命令最后 mvn exec:java & # $! 变量获取最近一个后台启动的进程PID,就是我们要的Java进程ID echo $! > "$PID_FILE" echo "程序启动成功,PID为$!" ;; stop) if [ ! -f "$PID_FILE" ]; then echo "程序未运行,没有找到PID文件" exit 1 fi # 读取PID杀进程 kill "$(cat $PID_FILE)" # 删除PID文件 rm -f "$PID_FILE" echo "程序已停止" ;; *) echo "usage: $0 {start|stop}" exit 1 ;; esac exit 0
关键修改点说明
- 去掉了包裹
cd和mvn命令的括号,避免启动子Shell - 使用
&将mvn命令放到后台运行,此时Bash内置变量$!会自动保存最后一个后台进程的PID,也就是你启动的Java进程ID - 统一使用绝对路径定义PID文件和工作目录,避免在不同路径执行脚本时出现文件找不到的问题
- 增加了运行状态判断,避免重复启动、重复停止的异常
内容的提问来源于stack exchange,提问作者A. Vreeswijk
相关产品推荐
相关产品推荐

