nohup启动java jar包秒退的根本原因是未切断stdin,需加

nohup 启动 Java JAR 包时进程一启动就退出
根本原因通常是 nohup 没有真正接管标准输入(stdin),而某些 Spring Boot 或框架启动过程会尝试读取 stdin,一旦失败就静默退出。不是“没运行”,而是秒退了,连日志都来不及写。
- 必须加
切断 stdin,否则很多 Java 应用(尤其带 Actuator 或交互式初始化逻辑的)会挂掉 -
nohup默认把 stdout 和 stderr 合并重定向到nohup.out,但你通常想要分开控制——比如只让 error 进error.log,info 级别进app.log - 别用
nohup java -jar app.jar &这种裸写法,缺/dev/null和显式重定向,90% 的“启动即消失”都出在这儿
正确写法示例:
nohup java -jar app.jar < /dev/null > app.log 2>&1 &
如何让日志按级别分离且避免 nohup.out 污染
nohup 本身不支持日志分级,它只管重定向流。真正起作用的是 shell 的重定向语法组合,以及你是否在应用里配好了日志框架(如 Logback)。
- 如果只要物理分离:用
2> error.log > app.log把 stderr 单独甩出去,但注意 Java 默认把System.err和System.out都打到 console,Logback/Spring Boot 日志默认走的是 SLF4J → Logback,不走 stdout/stderr —— 所以光靠 shell 重定向没用 - 真正可控的方式:关闭 Logback 的 console appender,在
logback-spring.xml里只保留RollingFileAppender,再用nohup ... > /dev/null 2>&1 &把 JVM 层面的杂输出(比如 GC 日志、-Xlog 输出)彻底屏蔽 - 别指望
nohup.out能当正式日志用——它不可控、不轮转、权限混乱,上线前务必用> /dev/null 2>&1干掉它
Java 进程后台运行后查不到或 kill 不掉
常见现象是 ps aux | grep java 找不到进程,或者 kill -9 失效。本质是进程启动后“脱离了终端会话”,但没真正变成守护进程,或者被 systemd / supervisord 接管了却没意识到。
立即学习“Java免费学习笔记(深入)”;
-
nohup只是忽略 SIGHUP,并不创建 daemon 进程;它仍属于当前 session 的子进程,只是父 shell 退出后它由 init(PID 1)收养——所以ps -ef能看到,但ps aux | grep java可能因参数过长被截断,改用ps -ef | grep app.jar - 别用
killall java,可能干掉其他项目;精准杀法是lsof -i :8080(假设端口是 8080)找 PID,再kill -15 <pid></pid>(优雅停机) - 如果用了
&但忘了nohup,进程会在终端关闭时收到 SIGHUP 直接退出——这不是 bug,是 POSIX 行为
Spring Boot 项目用 nohup 启动后 actuator / shutdown 端点失效
不是端点关了,是 Spring Boot 默认的 /actuator/shutdown 是 POST 请求,且需要开启(management.endpoint.shutdown.post.enabled=true),但更常见的问题是:你压根没暴露这个端点,或者防火墙/反向代理拦掉了。
- 确认配置项:
management.endpoints.web.exposure.include=*或至少包含shutdown,health,info -
nohup不影响 HTTP 端口监听,只要server.port没被占用、没 bind 到127.0.0.1(导致外网访问不了),端点就可用 - 别在生产环境开
/actuator/shutdown,除非你明确做了鉴权(比如加 Spring Security),否则等于给任何人一个远程 kill 开关
复杂点在于:日志路径权限、JVM 参数(尤其是堆外内存和文件描述符限制)、以及 Linux 的 systemd 替代方案其实更稳——但如果你现在只能用 nohup,那就盯死 stdin、stdout、stderr 三者的流向,其余都是表象。










