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

如何向ProcessBuilder发送字符串输入并通过线程实现CLI自动化

实现代码

你需要分别处理进程的输入写入、输出读取逻辑,两者要放在不同线程避免阻塞,以下是可直接运行的实现:

import java.io.*;

class Envir {
    private Process process;
    private BufferedWriter commandWriter;
    private Thread outputReaderThread;

    public void run() throws IOException {
        ProcessBuilder builder = new ProcessBuilder("bash");
        builder.redirectInput(ProcessBuilder.Redirect.PIPE);
        builder.redirectOutput(ProcessBuilder.Redirect.PIPE);
        builder.redirectErrorStream(true); // 合并错误流到输出流,不用单独读错误流
        process = builder.start();

        // 初始化命令输入流,用来给bash发命令
        commandWriter = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));

        // 启动独立线程读取bash的输出内容,避免缓冲区满导致进程阻塞
        outputReaderThread = new Thread(() -> {
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    // 这里可以自定义输出处理逻辑,比如打印、解析返回结果
                    System.out.println("[Bash Output] " + line);
                }
            } catch (IOException e) {
                if (!process.isAlive()) {
                    System.out.println("进程已退出,输出读取结束");
                } else {
                    e.printStackTrace();
                }
            }
        });
        outputReaderThread.start();
    }

    // 对外暴露的发命令方法
    public void sendCommand(String command) throws IOException {
        if (commandWriter == null || !process.isAlive()) {
            throw new IllegalStateException("bash进程未启动");
        }
        commandWriter.write(command);
        commandWriter.newLine(); // bash按行解析命令,必须加换行才会执行
        commandWriter.flush(); // 强制刷出缓冲区,命令立刻发送
    }

    // 销毁进程和释放资源
    public void stop() throws InterruptedException, IOException {
        sendCommand("exit"); // 正常退出bash
        process.waitFor();
        commandWriter.close();
        outputReaderThread.join();
        process.destroy();
    }

    public static void main(String[] args) throws Exception {
        Envir envir = new Envir();
        envir.run();
        // 测试执行命令
        envir.sendCommand("env python3 --version");
        envir.sendCommand("echo 测试命令执行");
        envir.sendCommand("ls -l");
        // 等待3秒获取所有输出后退出
        Thread.sleep(3000);
        envir.stop();
    }
}
核心逻辑说明
  • 命令写入逻辑:通过Process.getOutputStream()获取bash进程的标准输入流,包装为BufferedWriter后即可按行发送自定义命令,每次发送必须加换行符并执行flush()操作,否则命令会停留在缓冲区不被执行。
  • 输出读取逻辑:必须单独开线程读取进程的输出流,因为流读取是阻塞操作,如果放在主线程会卡住命令发送逻辑;如果不及时读取输出,缓冲区占满后bash进程会直接阻塞,不再执行任何命令。
  • 资源回收:执行完成后先发送exit命令正常退出bash,再等待进程结束、关闭所有流、销毁进程,避免出现僵尸进程。
注意事项
  • 如果要和交互式CLI(比如python REPL、mysql命令行)交互,可以在发送命令后增加输出匹配逻辑,检测到指定特征返回后再发下一条命令,避免命令发送过快导致执行异常。
  • 可以根据需求修改输出读取线程的逻辑,比如把输出存到队列里供其他业务逻辑消费。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 09:15:03