Java调用Linux命令获取Jetty服务器当前运行进程的问题
解决Java代码获取Linux下正在运行的Jetty进程问题
我之前在做服务器监控工具时也碰到过一模一样的问题!明明终端里执行命令能精准拿到正在运行的Jetty进程,放到Java代码里就带出一堆已终止的记录,折腾了好一会儿才搞定。咱们一步步来解决:
为什么会拿到已终止的进程记录?
你用的Linux命令(比如ps aux | grep jetty)默认会列出所有含"jetty"关键词的进程,包括:
- 正在运行的Jetty主进程
- 执行
grep jetty的临时进程(执行完就终止) - 已变成**僵尸进程(defunct)**的Jetty进程(进程终止但父进程未回收资源)
所以得先过滤这些干扰项,终端里正确的命令是:
ps aux | grep jetty | grep -v grep | grep -v defunct
各部分作用:
grep -v grep:排除grep命令自身的临时进程grep -v defunct:排除已终止的僵尸进程
为什么集成到Java里失效?
问题出在Java的Runtime.exec()方法——它默认不会启动shell解析管道|、重定向这些符号,而是把整个命令拆成独立参数,导致管道符号被当成普通字符串传给ps,自然得不到正确结果。
解决办法是把整个命令交给shell执行,用bash -c包裹你的命令即可。
完整Java代码示例
方式1:获取完整进程信息
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class JettyMonitor { public static void main(String[] args) { // 用bash -c执行带管道的完整命令 String shellCommand = "bash -c \"ps aux | grep jetty | grep -v grep | grep -v defunct\""; try { Process process = Runtime.getRuntime().exec(shellCommand); BufferedReader inputReader = new BufferedReader(new InputStreamReader(process.getInputStream())); String processLine; boolean hasRunningJetty = false; // 逐行读取进程输出 while ((processLine = inputReader.readLine()) != null) { hasRunningJetty = true; System.out.println("正在运行的Jetty进程:\n" + processLine); } if (!hasRunningJetty) { System.out.println("未检测到正在运行的Jetty进程"); } // 等待命令执行完成 process.waitFor(); inputReader.close(); } catch (IOException | InterruptedException e) { e.printStackTrace(); } } }
方式2:仅判断是否运行(更简洁)
如果只需要知道Jetty是否在运行,不需要完整进程信息,可以用pgrep命令(专门查找正在运行的进程ID):
public class JettyStatusChecker { public static boolean isJettyRunning() { // pgrep -f 匹配包含指定关键词的进程命令行 String checkCommand = "bash -c \"pgrep -f jetty\""; try { Process process = Runtime.getRuntime().exec(checkCommand); int exitCode = process.waitFor(); // pgrep找到进程返回0,未找到返回1 return exitCode == 0; } catch (IOException | InterruptedException e) { e.printStackTrace(); return false; } } public static void main(String[] args) { if (isJettyRunning()) { System.out.println("Jetty服务器正在运行"); } else { System.out.println("Jetty服务器未运行"); } } }
额外注意事项
- 如果你的Jetty进程名不含"jetty"(比如自定义jar包名启动),要调整
grep或pgrep的关键词,比如换成Jetty主类名org.eclipse.jetty.server.Server - 确保运行Java程序的用户有足够权限查看Jetty进程(比如Jetty用root启动,Java程序也要用root权限运行)
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

