Though I'm using Linux, this should apply to Windows as well. The below sample code executes a shell process multiple times, waiting for each process to complete before continuing:
import java.util.Date;
public class Test {
public static void main(final String[] args) {
for (int i = 0; i < 5; i++) {
System.out.println("Executing command " + i + ": " + (new Date()));
try {
final Process p = new ProcessBuilder("sh", "-c", "sleep 2;").redirectErrorStream(true).start();
p.waitFor();
} catch (final Throwable t) {
t.printStackTrace();
}
}
}
}
This outputs:
Executing command 0: Tue Apr 17 09:19:55 EDT 2012
Executing command 1: Tue Apr 17 09:19:57 EDT 2012
Executing command 2: Tue Apr 17 09:20:00 EDT 2012
Executing command 3: Tue Apr 17 09:20:02 EDT 2012
Executing command 4: Tue Apr 17 09:20:04 EDT 2012
Printing the result (exit value) of Runtime.exec(String)
using a value of sh -c 'sleep 2;'
, I get 2
(failed execution); but the result of Runtime.exec(String[])
using new String[] {"sh", "-c", "sleep 2;"}
returns 0
(successful execution). Looking at the Runtime.java
and ProcessBuilder.java
sources, Runtime.exec(String)
splits the string out using a StringTokenizer
, which uses default delimiters of " \t\n\r\f"
. So executing Runtime.exec("sh -c 'sleep 2;'")
will break the command string out as the array ["sh", "-c", "'sleep", "2;'"]
, which contains invalid arguments.
To ensure commands are executed properly, it's best to use Runtime.exec(String[])
instead of Runtime.exec(String)
.
Your cmd /c start /min file1.bat
command string is probably not working when split out to ["cmd", "/c", "start", "/min", "file1.bat"]
. The following should work:
Runtime.getRuntime().exec(new String[] {"cmd", "/c", "start /min file1.bat"});