You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过shell脚本监测nohup.out异常自动重启对应Java Jar进程

原有脚本问题排查
  • 变量引用错误:定义的异常关键词变量是STOPPED_MESSAGE,但grep判断时错误使用了不存在的$STOPPED,导致异常匹配逻辑完全失效
  • 语法错误:if [ $processId -eq ...]中]前缺少空格,会触发shell语法报错
  • 进程匹配逻辑缺陷:如果没有匹配到dataAdapter进程,processId为空,数值判断会直接报错;如果同时存在多个匹配进程,processId会拼接多个PID,无法正常执行判断和kill操作
  • 工作目录缺失:脚本未切换到SERVICE_PATH目录,crontab执行时默认工作目录是执行用户的家目录,会找不到dataAdapter.jar包
  • 无效操作:给日志文件nohup.out加执行权限完全没必要,属于冗余操作
  • 异常匹配规则不合理:grep -Fxq是精确匹配整行,而异常栈一般是多行输出,UnknownHostException只会是某一行的部分内容,匹配规则会失效
  • 进程操作逻辑不合理:直接使用kill -9强制杀进程,可能导致jar包业务数据丢失;杀进程后未确认进程已退出就删除日志、启动新进程,会出现旧进程仍占用日志文件、新进程启动失败等问题
  • 环境变量缺失:crontab执行时不会加载用户的全量环境变量,可能出现找不到java命令的问题
最优实现方案

优化后完整脚本

#!/bin/bash
# 配置参数
SERVICE_PATH=/app/application/DataAdapter
STOPPED_MESSAGE="java.net.UnknownHostException"
LOG_FILE=${SERVICE_PATH}/nohup.out
JAR_NAME=dataAdapter.jar
# 配置java绝对路径,避免crontab找不到命令,可通过which java查看实际路径替换
JAVA_PATH=/usr/bin/java

# 切换到工作目录
cd ${SERVICE_PATH} || exit 1

# 安全获取进程PID,只匹配jar包启动的进程,避免误杀
processId=$(pgrep -f "${JAR_NAME}")

# 第一步:判断进程是否存在
if [[ -n "${processId}" ]]; then
    # 进程存在,检查日志是否包含指定异常
    if grep -Fq "${STOPPED_MESSAGE}" "${LOG_FILE}"; then
        # 匹配到异常,先正常杀进程,等3秒没杀死再强制杀
        kill ${processId}
        sleep 3
        if pgrep -f "${JAR_NAME}" > /dev/null; then
            kill -9 ${processId}
        fi
        # 删除旧日志
        rm -f ${LOG_FILE}
        # 后台启动新进程
        nohup ${JAVA_PATH} -jar ${JAR_NAME} > ${LOG_FILE} 2>&1 &
        echo "检测到异常,已重启服务,新PID: $!"
    else
        echo "服务运行正常,无匹配异常,当前PID: ${processId}"
    fi
else
    # 进程不存在,直接启动
    rm -f ${LOG_FILE}
    nohup ${JAVA_PATH} -jar ${JAR_NAME} > ${LOG_FILE} 2>&1 &
    echo "检测到服务未运行,已启动,新PID: $!"
fi

echo "任务执行完成"

脚本优化说明

  • 用pgrep -f匹配jar包启动的进程,比ps+grep更精准,避免误杀其他含dataAdapter关键字的进程
  • 增加工作目录切换,确保jar包和日志路径正确
  • 提前配置java绝对路径,避免crontab环境变量问题
  • 调整异常匹配逻辑,去掉精确整行匹配的-x参数,只要行内包含异常关键词就命中
  • 优化进程杀死逻辑,先发普通kill信号让进程优雅退出,超时再强制kill
  • 增加进程不存在的兜底启动逻辑,实现服务异常宕机也能自动拉起
  • 所有变量用花括号包裹,避免字符串拼接歧义
crontab配置说明
  • 先给脚本加执行权限:chmod +x /path/to/autoRestart.sh
  • 编辑crontab:执行crontab -e,添加如下配置(示例是每1分钟执行一次,可根据需求调整间隔):
*/1 * * * * /path/to/autoRestart.sh >> /app/application/DataAdapter/restart.log 2>&1
  • 配置说明:将脚本执行的日志输出到restart.log,方便排查定时任务执行问题,不要留空输出避免产生系统垃圾邮件

内容的提问来源于stack exchange,提问作者Tarik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 19:18:01