I have read many examples and ended up using the following code to execute a command line command from inside of a Java program.
public static void executeCommand(final String command) throws IOException,
InterruptedException {
System.out.println("Executing command " + command);
final Runtime r = Runtime.getRuntime();
final Process p = r.exec(command);
System.out.println("waiting for the process");
p.waitFor();
System.out.println("waiting done");
try (final BufferedReader b = new BufferedReader(new InputStreamReader(
p.getInputStream()))) {
String line;
while ((line = b.readLine()) != null) {
System.out.println(line);
}
}
}
I have tested it with a simple ls command and it works fine. When I try to run another command, it is taking forever (kept running for 25 minutes and did not stop yet).
When I execute a tabix command on the command line, I get the following statistics
4.173u 0.012s 0:04.22 99.0% 0+0k 0+0io 0pf+0w
Hence it should finish fast.
The command is
time tabix file pos1 pos2 ... pos190 > /dev/null
Could the problem be that the tabix command includes > /dev/null at the end? If not, what could cause this issue?
解决方案
You need to attach the reader to the process before calling it's waitFor. Without that it could fill it's allocated output buffer and then block - but only for big output, small (e.g. test) output will seem to be fine.
public static void executeCommand(final String command) throws IOException, InterruptedException {
System.out.println("Executing command " + command);
// Make me a Runtime.
final Runtime r = Runtime.getRuntime();
// Start the command process.
final Process p = r.exec(command);
// Pipe it's output to System.out.
try (final BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
String line;
while ((line = b.readLine()) != null) {
System.out.println(line);
}
}
// Do this AFTER you've piped all the output from the process to System.out
System.out.println("waiting for the process");
p.waitFor();
System.out.println("waiting done");
}