【问题标题】:How to start `program1 | program2` with ProcessBuilder without using a shell?如何启动`program1 | program2` 与 ProcessBuilder 不使用外壳?
【发布时间】:2023-04-11 03:14:01
【问题描述】:

我想启动两个程序(如ProcessBuilder),这样第一个程序的输出就是第二个程序的输入。我还想要:

  1. 为了避免使用 shell(这样我就可以传递带空格的参数而无需转义);
  2. 为了避免所有数据流入父 Java 进程并返回(即有单独的线程只是为了从一个进程的 InputStream 复制到另一个进程的 OutputStream)。

如何做到这一点?

相关:Building a process pipe with ProcessBuilder in Java 7,但它使用 shell...

【问题讨论】:

  • 无论如何你都必须实例化两个ProcessBuilders,因为program1program2 将是两个独立的进程
  • 如何互连它们的输出/输入流以直接从 program1 流向 program2,而不通过 java?
  • 但是你必须... 就像 shell 创建匿名管道一样,你必须在 Java 中这样做。没有其他方法可以解决这个问题。
  • @fge, 1. 如何在Java中创建匿名管道? 2、如何将创建的管道指定给ProcessBuilder? (没有 JNI)

标签: java process pipe io-redirection


【解决方案1】:

迟到的答案;但您可以使用命名管道。通过mkfifo 创建第一个。然后在你的 Java 代码中:

ProcessBuilder pb1 = new ProcessBuilder("gunzip", "-c", "log.gz");
ProcessBuilder pb2 = new ProcessBuilder("grep", "error");

File pipe = new File(NAMED_PIPE_PATH); // NAMED_PIPE_PATH points to what you created via mkfifo

pb1.redirectOutput(ProcessBuilder.Redirect.to(pipe));
pb2.redirectInput(ProcessBuilder.Redirect.from(pipe));

ProcessStartThread pst1 = new ProcessStartThread(pb1);
ProcessStartThread pst2 = new ProcessStartThread(pb2);
pst1.start();
pst2.start();

请注意,ProcessStartThread 是一个简单的自定义类,它扩展了 Thread,除了在传递的 ProcessBuilder 实例上调用 start() 之外,基本上什么都不做。必须从单独的线程完成此操作的原因是 ProcessBuilder.start() 将挂起,直到连接命名管道的另一端(它需要打开输入/输出才能开始执行)。

编辑:这里也是ProcessStartThread 类:

class ProcessStartThread extends Thread {
    private ProcessBuilder procBuilder;
    private Process proc;
    public ProcessStartThread(ProcessBuilder procBuilder) {
        this.procBuilder = procBuilder;
        this.proc = null;
    }
    public void run() {
        try { this.proc = this.procBuilder.start(); } 
        catch ( Exception e ) { e.printStackTrace(); }
    }
    public Process getProcess() {
        return this.proc;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    • 1970-01-01
    相关资源
    最近更新 更多