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

Java执行wmctrl命令获取Linux应用名称异常,求正确写法

解决Java执行带管道的wmctrl命令无效问题

问题核心在于Runtime.exec()不会自动解析Shell的管道符号|,它会把整个命令字符串当作单个程序执行,导致awk部分完全没被调用,自然返回wmctrl -l的完整输出。以下是两种可行的解决方式:

方法1:通过Shell执行完整命令

把命令交给系统Shell(如bash/sh)处理,让Shell解析管道符号。修改后的Java代码如下:

String str;
Process p;
try {
    // 用bash -c包裹完整命令,注意转义内部引号
    String command = "bash -c \"wmctrl -l | awk '{$1=\\\"\\\"; $2=\\\"\\\"; $3=\\\"\\\"; print}'\"";
    p = Runtime.getRuntime().exec(command);
    BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
    // 必须读取错误流,避免进程因缓冲区满阻塞
    BufferedReader errBr = new BufferedReader(new InputStreamReader(p.getErrorStream()));
    
    while ((str = br.readLine()) != null) {
        activeWindowtitles.add(str);
        System.out.println(str);
    }
    // 输出错误信息用于调试(可选)
    String errStr;
    while ((errStr = errBr.readLine()) != null) {
        System.err.println(errStr);
    }
    
    p.waitFor();
    p.destroy();
} catch (Exception ex) {
    ex.printStackTrace(); // 不要吞掉异常,方便排查问题
}

方法2:Java内部处理输出(无需依赖awk)

直接执行wmctrl -l,在Java代码中手动过滤每行的前三个字段,避免Shell转义的麻烦,同时更可控:

String str;
Process p;
try {
    String command = "wmctrl -l";
    p = Runtime.getRuntime().exec(command);
    BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
    BufferedReader errBr = new BufferedReader(new InputStreamReader(p.getErrorStream()));
    
    while ((str = br.readLine()) != null) {
        // 按任意空白符分割,最多分成4部分,保留第4部分及之后的内容
        String[] parts = str.split("\\s+", 4);
        if (parts.length >= 4) {
            String appName = parts[3];
            activeWindowtitles.add(appName);
            System.out.println(appName);
        }
    }
    
    // 读取错误流
    String errStr;
    while ((errStr = errBr.readLine()) != null) {
        System.err.println(errStr);
    }
    
    p.waitFor();
    p.destroy();
} catch (Exception ex) {
    ex.printStackTrace();
}

关键注意点

  • 不要空吞异常:原代码的空catch块会隐藏错误,改成打印堆栈信息才能快速排查问题。
  • 必须读取错误流:进程的错误输出如果不读取,缓冲区满时会导致进程挂起,无法正常结束。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 16:07:50