I have two processes defined by processBuilders:
ProcessBuilder pb1 = new ProcessBuilder (...)
ProcessBuilder pb2 = new ProcessBuilder (...)
I want the output of pb1 to be the input to pb2.
I found in the documentation that I can make the input of pb2 to be read from another process by using pipe:
pb2.redirectInput(Redirect.PIPE);
However, how can I specify that I want this pipe to read from the output of pb1?
static ProcessBuilder.Redirect INHERIT Indicates that subprocess I/O source or destination will be the same as those of the current process.
static ProcessBuilder.Redirect PIPE Indicates that subprocess I/O will be connected to the current Java process over a pipe.
So I don't think one of these will help you redirecting the output of one process to the input of another process. You have to implement it yourself.
Implementation:
public class RedirectStreams {
public RedirectStreams(Process process1, Process process2) {
    final Process tmpProcess1 = process1;
    final Process tmpProcess2 = process2;
    new Thread(new Runnable() {
        @Override
        public void run() {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(tmpProcess1.getInputStream()));
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(tmpProcess2.getOutputStream()));
            String lineToPipe;
            try {
                while ((lineToPipe = bufferedReader.readLine()) != null){
                    System.out.println("Output process1 / Input process2:" + lineToPipe);
                    bufferedWriter.write(lineToPipe + '\n');
                    bufferedWriter.flush();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();
}
}
This one can surely be designed nicer and I haven't tested, if it runs's safe, but it does the job.
Usage:
RedirectStreams redirectStreams = new RedirectStreams(process1,process2);
Test:
public class ProcessPipeTest {
@Test public void testPipe(){
    try {
        Process process1 = new ProcessBuilder("/bin/bash").start();
        Process process2 = new ProcessBuilder("/bin/bash").start();
        RedirectStreams redirectStreams = new RedirectStreams(process1,process2);
        
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(process1.getOutputStream()));
        String command = "echo echo echo";
        System.out.println("Input process1: " + command);
        bufferedWriter.write(command + '\n');
        bufferedWriter.close();
        
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process2.getInputStream()));
        String actualOutput = bufferedReader.readLine();
        System.out.println("Output process2: " + actualOutput);
        assertEquals("echo",actualOutput);
    } catch (IOException e) {
        e.printStackTrace();
    }
}
}
Output:
Input process1: echo echo echo
Output process1 / Input process2:echo echo
Output process2: echo
As of JDK 9, you can use startPipeline like so:
ProcessBuilder.startPipeline(
    Arrays.asList(
        new ProcessBuilder(...),
        new ProcessBuilder(...),
        ...
    )
)
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With