How to have input-redirection with Javas ProcessBuilder?

52 Views Asked by At

How can I apply input redirection to Javas ProcessBuilder?

E.g. use cat of Linux

cat x.txt > output.txt

My code

// read x.txt with cat and redirect the output to output.txt
public static void main (String args []) throws Exception
{
    List <String> params = new ArrayList <String> ();
    params.add ("cat");
    params.add ("x.txt");       
    ProcessBuilder pb = new ProcessBuilder (params);
    pb.redirectOutput (new File ("output.txt"));
    Process p = pb.start ();
    p.waitFor (3, TimeUnit.SECONDS);
    System.out.println ("exit="+p.exitValue());
}

That works fine! But how to change from file to input-redirection?

cat << END > output

I tried this - but does not work.

public static void main (String args []) throws Exception
{
    List <String> params = new ArrayList <String> ();
    params.add ("cat");
    params.add ("/dev/stdin");
    params.add ("<<";
    params.add ("END");
    
    ProcessBuilder pb = new ProcessBuilder (params);
    pb.redirectOutput (new File ("output.txt"));
    Process p = pb.start ();
    OutputStream os = p.getOutputStream ();
    os.write ("\nblabla\nEND\n".getBytes ());
    p.waitFor (3, TimeUnit.SECONDS);
    System.out.println ("exit="+p.exitValue());
}

No matter what I tried it returned with 1 (instead of 0 for success) or did not finish.

3

There are 3 best solutions below

0
DuncG On

The command cat << END > output is a shell command so you need to run it via shell as

 List <String> params = List.of("/bin/sh", "-c", "cat << END > output")
0
jurez On

You need to call os.close() to let the process know that no more data is coming.

0
chris01 On

I solved it by skipping the

<<END

but then opened an OutputStream after starting the process. Over that I put the files content into the process. Flushing and closing of the stream is important.

ProcessBuilder pb = new ProcessBuilder (params);
Process p = pb.start ();
                
OutputStream os = p.getOutputStream ();
os.write (content_string);  
os.flush ();
os.close ();