编写Bash脚本实现Jenkins编译后重启Java应用,现有screen脚本不生效
问题原因
你当前脚本执行失败主要有以下几个原因:
- 时序与会话初始化问题:你拆分了创建screen会话和发送执行命令两步,
screen -d -m刚创建的后台会话尚未完成初始化,此时发送-X指令会执行失败,没有前台任务的screen会话会自动终止,所以screen -ls查询不到结果。 - 会话终止逻辑问题:如果
java -jar命令执行失败(比如jar路径错误、Java环境不存在、端口被占用),进程退出后screen会话没有运行中的前台任务,也会自动结束。 - 环境变量问题:Jenkins执行脚本时默认使用jenkins用户的运行环境,和你登录服务器时的用户环境变量不一致,大概率会出现找不到
java命令、无jar包路径访问权限的问题,导致Java进程启动失败。 - 关闭指令隐患:如果不存在对应名称的screen会话,
screen -X -S JavaTelegramBot quit会返回非零退出码,如果你的脚本开启了set -e配置,会直接终止后续执行逻辑。
解决方案
修正后的脚本
不需要拆分创建会话和发送命令的步骤,screen支持启动时直接指定要执行的任务,同时提前处理环境变量和会话存在性判断,脚本示例如下:
#!/bin/bash # 替换为你的jar包绝对路径 JAR_PATH="/data/app/JavaTelegramBot.jar" # 替换为你的screen会话名称 SCREEN_NAME="JavaTelegramBot" # 替换为你的服务器Java实际安装路径,避免Jenkins环境找不到Java命令 export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 export PATH=$JAVA_HOME/bin:$PATH # 判断旧会话是否存在,存在则先关闭 if screen -list | grep -q "${SCREEN_NAME}"; then screen -X -S "${SCREEN_NAME}" quit # 等待2秒确保旧进程完全退出,避免端口占用 sleep 2 fi # 直接启动screen后台会话并运行Java应用 screen -d -m -S "${SCREEN_NAME}" java -jar "${JAR_PATH}" # 可选:启动校验逻辑 sleep 1 if screen -list | grep -q "${SCREEN_NAME}"; then echo "应用启动成功,screen会话名称:${SCREEN_NAME}" else echo "应用启动失败,请检查jar路径、Java环境、应用启动日志" exit 1 fi
额外注意事项
- 所有路径必须使用绝对路径,Jenkins任务的默认工作目录和你手动执行脚本的目录可能不同,相对路径会导致找不到jar包。
- 如果启动失败可以先去掉screen逻辑,直接在Jenkins脚本中执行
java -jar 你的jar包绝对路径,查看控制台输出的报错信息,定位是应用本身问题还是环境问题,排查完成后再套入screen逻辑。 - 如需留存应用日志,可以将启动命令修改为
screen -d -m -S "${SCREEN_NAME}" java -jar "${JAR_PATH}" >> /var/log/java-telegram-bot.log 2>&1,方便后续排查问题。
内容的提问来源于stack exchange,提问作者Alex F
相关产品推荐
相关产品推荐

