Java 如何在不使用shell的情况下使用ProcessBuilder启动“program1 | program2”?

Java 如何在不使用shell的情况下使用ProcessBuilder启动“program1 | program2”?,java,process,pipe,io-redirection,Java,Process,Pipe,Io Redirection,我想启动两个程序(如在ProcessBuilder中),这样第一个程序的输出就是第二个程序的输入。我还想: 避免使用shell(这样我就可以传递带有空格的参数,而无需逃避麻烦) 避免所有数据流入父Java进程并返回(即,使用单独的线程仅将一个进程的InputStream复制到另一个进程的OutputStream) 如何做到这一点 相关:,但它使用shell…延迟回答;但您可以使用命名管道。首先通过mkfifo创建一个。然后在Java代码中: ProcessBuilder pb1 = new Pr

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

  • 避免使用shell(这样我就可以传递带有空格的参数,而无需逃避麻烦)
  • 避免所有数据流入父Java进程并返回(即,使用单独的线程仅将一个进程的InputStream复制到另一个进程的OutputStream)
  • 如何做到这一点


    相关:,但它使用shell…

    延迟回答;但您可以使用命名管道。首先通过
    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;
        }
    }
    

    无论如何,您必须实例化两个
    ProcessBuilder
    s,因为
    program1
    program2
    将是两个独立的进程如何互连其输出/输入流以直接从program1流向program2,而不必经过java?但是您必须。。。与shell创建匿名管道的方式相同,您必须在Java中这样做。这是没有别的办法的。@fge,1。如何在Java中创建匿名管道?2.如何将创建的管道指定给ProcessBuilder?(不含JNI)