I am currently using ProcessBuilder to run commands from a java server. This server is to replace an old Perl server, and a lot of our legacy code specifies platform specific c
I think the quotes are being interpreted by the shell. Instead, put the command in a shell script:
$ cat temp.sh
#!/bin/sh
perl -e "print 5"
and execute it:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class PBTest {
public static void main(String[] args) {
ProcessBuilder pb = new ProcessBuilder("./temp.sh");
pb.redirectErrorStream(true);
try {
Process p = pb.start();
String s;
BufferedReader stdout = new BufferedReader (
new InputStreamReader(p.getInputStream()));
while ((s = stdout.readLine()) != null) {
System.out.println(s);
}
System.out.println("Exit value: " + p.waitFor());
p.getInputStream().close();
p.getOutputStream().close();
p.getErrorStream().close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Console:
5
Exit value: 0
Are you able to use the overloaded Runtime.exec(String) that takes a single String and runs that as the entire command?
The following works for me on Windows:
Process p = Runtime.getRuntime().exec("perl -e \"print 5\"");
System.out.println(IOUtils.toString(p.getInputStream()));
p.destroy();
This is more or less what Runtime.exec(String) is doing:
public static void main(String [] args) throws Exception {
Process p = new ProcessBuilder(getCommand("perl -e \"print 5\"")).start();
System.out.println(IOUtils.toString(p.getInputStream()));
p.destroy();
}
private static String[] getCommand(String input) {
StringTokenizer tokenizer = new StringTokenizer(input);
String[] result = new String[tokenizer.countTokens()];
for (int i = 0; tokenizer.hasMoreTokens(); i++) {
result[i] = tokenizer.nextToken();
}
return result;
}