1

I have a perl script that i'm trying to execute through shell. The normal UNIX shell invocation is do is: /home/projects/bumble/script.pl --input /home/input/input.txt > /home/output/output.txt.

To do this in Java I wrote a function:

public void runCommand(String command, File directory) { 
    final ProcessBuilder pb = new ProcessBuilder(command);
    pb.directory(directory);
    final Process process = pb.start();
    if(process.waitFor() != 0) {
        throw new RuntimeException("ERROR");
    }
}

I call this:

String command = "/home/projects/bumble/script.pl --input /home/input/input.txt > /home/output/output.txt";
File directory = new File("/home/projects/bumble");
runCommand(command,directory);

The exception I get is: java.io.IOException: ... Cannot run program error=2, No such file or directory

I notice here: java.io.IOException: Cannot run program error=2, No such file or directory, implies that running programs given a full input with > into a completely different directory would fail. If I just run the command /home/projects/bumble/script.pl --input /home/input/input.txt, also fails with the same error. I run it directly through shell, it does work. Is there something I am missing or doing incorrectly?

Community
  • 1
  • 1
Niru
  • 1,407
  • 1
  • 28
  • 47
  • I assume `script.pl`'s first line is `#!/usr/bin/perl` or something similar? I'm not sure if `ProcessBuilder` understands this, so you may have to get `ProcessBuilder` to run the shell, i.e. `String command = "sh /home/projects/...` (or even `"/bin/sh /home/projects/...`). I've never used Java on Linux/Unix, so I'm not sure about this, but it may be worth a try. – ajb Apr 19 '14 at 01:07
  • Yes, its the first line. Thanks, I will try that. – Niru Apr 19 '14 at 01:10
  • Still errors, but with /bin/sh not found. – Niru Apr 19 '14 at 01:39
  • Where is "sh" located on your Unix system? If it's in some other path besides `/bin`, then try using that, wherever it is. – ajb Apr 19 '14 at 01:43

1 Answers1

1

Runtime.exec() traps: http://www.javaworld.com/article/2071275/core-java/when-runtime-exec---won-t.html?page=3

2 problems with the code: Command should be broken down into a String[] such as:

String[] command = {"perl", "/home/projects/bumble/script.pl", "--input", "/home/input/input.txt"}

Output needs to be handled seperately without the redirect ">". To do this, ProcessBuilder has Redirect. http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.Redirect.html

Programmatically the function is:

public static void runCommand(final String[] command, final File directory, final File output) throws IOException, InteruptException {
    final ProcessBuilder pb = new ProcessBuiler(command); 
    pb.redirectErrorStream(true); //optional; easier for this case to only handle one stream
    pb.redirectOutput(Redirect.to(output));
    final Process p = pb.start();

    if(p.waitFor != 0) {
        //throw an exception / return error message
    }
}
Niru
  • 1,407
  • 1
  • 28
  • 47