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

Java Gradle插件开发:如何打印Shell命令的输出而非执行结果?

问题:如何打印Shell命令的输出内容而非执行状态?

我并非Java程序员,只是一名技术爱好者!我编写了一个基于Java的Gradle插件,用于执行Shell命令(本例中为Git命令),代码如下:

BufferedReader execShellCmd(final String cmd) {
    BufferedReader br = null;
    ProcessBuilder pb = new ProcessBuilder();
    if (isWindows()) {
        pb.command("cmd.exe", "/c", cmd);
    }
    else {
        pb.command("sh", "-c", cmd);
    }
    try {
        Process p = pb.start();
        br = new BufferedReader(new InputStreamReader(p.getInputStream()));

        exitVal = p.waitFor();
        if (exitVal > 0) {
            System.out.printf("%s failed, err no: %d", cmd, exitVal);
        }
    }
    catch (IOException e){
        System.out.println("ERROR: I/O exception");
        e.printStackTrace();
    }
    catch (InterruptedException e){
        System.out.println("ERROR: Interrupt exception");
        e.printStackTrace();
    }
    return br;
}

...
cmd = "if [[ -n $(git status -s) ]] ; then filelist=`git status -s` ; git commit -a -m \""+commitMsg+"\";; git push origin "+getSourceBranch()+":"+getSourceBranch()+" ; else echo \"No changes detected\"; fi";
execShellCmd(cmd);

我希望打印传入的cmd的输出内容,而非指代表成功(exitVal==0)或失败(exitVal>0)的执行结果,请问该如何实现?


解决方案

你需要读取命令执行后返回的输入流内容并打印,同时建议合并错误流避免进程阻塞,具体修改如下:

修改后的代码

// 调整方法为直接打印输出,无需返回BufferedReader
void execShellCmd(final String cmd) {
    ProcessBuilder pb = new ProcessBuilder();
    if (isWindows()) {
        pb.command("cmd.exe", "/c", cmd);
    } else {
        pb.command("sh", "-c", cmd);
    }
    // 将错误输出合并到标准输出,这样可以一次性读取所有输出
    pb.redirectErrorStream(true);
    
    try {
        Process p = pb.start();
        // 读取命令的输出内容
        BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line;
        System.out.println("=== 命令执行输出 ===");
        // 循环读取每一行并打印
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
        br.close();

        exitVal = p.waitFor();
        if (exitVal > 0) {
            System.out.printf("%n%s 执行失败,错误码: %d%n", cmd, exitVal);
        }
    } catch (IOException e) {
        System.out.println("ERROR: I/O异常");
        e.printStackTrace();
    } catch (InterruptedException e) {
        System.out.println("ERROR: 中断异常");
        e.printStackTrace();
    }
}

// 调用方式不变
cmd = "if [[ -n $(git status -s) ]] ; then filelist=`git status -s` ; git commit -a -m \""+commitMsg+"\";; git push origin "+getSourceBranch()+":"+getSourceBranch()+" ; else echo \"No changes detected\"; fi";
execShellCmd(cmd);

关键说明

  • pb.redirectErrorStream(true):把命令的错误输出(比如git命令的错误提示)合并到标准输出流,避免因为错误输出缓冲区满导致进程卡住。
  • 循环读取BufferedReader的每一行并打印:这样就能完整输出命令执行的所有内容,包括git提交的反馈、push结果或者"No changes detected"的提示。
  • 调整方法返回值为void:因为现在直接在方法内打印输出,不需要返回流对象;如果你需要后续处理输出内容,可以把输出收集成字符串列表返回后再处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 09:55:27