Hello,


Sorry to revive this request, but I think this is as simple but very useful method that must be present on Java 7.

No one have an opinion on this?

Fred,


Le 17 septembre 2009 09:16, Frédéric Martini <frederic.martini@gmail.com> a écrit :
Hello (before to start, sorry for my bad english)


I have seen in the last JDK's build that ProcessBuilder allow to
manage the process I/O more efficiently.
In particular, the inheritIO() set the subprocess standard I/O to be
the same as those of the current Java process, and offer a behavior
"equivalent" to the standard C library function system(). This is very
great an usefull !

But there is another BIG difference between ProcessBuilder and the C
library function system() : ProcessBuilder execute an application, and
C system() evaluate a command-line using the OS's shell. So C's
system() can use a lot of OS's specific syntax ($ENV or %ENV%, * ?,
pipe, redirect, etc...) witch is incorrect on a ProcessBuilder
(because this syntax is not interpreted but directly passed to the
application).

This is a common misunderstanding for Java's developer...


My proposal simply consist to add a method that create a
ProcessBuilder pre-filled with a shell command's line, by invoking the
OS's shell ("/bin/sh" on Unixes, "command.com" on Win9x, "cmd.exe" on
WinNT, etc. ? ) in order to evaluate a more complex command-line.
A "basic" implementation can be like this :

======================================================================

      /**
       * Create a new ProcessBuilder initialized to call an OS's
       * specific command-line.
       */
      public static ProcessBuilder createShellFor(String commandLine) {
              String osName = System.getProperty("os.name");
              if (osName.startsWith("Windows")) {
                      if (osName.startsWith("Windows 95") ||
                       osName.startsWith("Windows 98") ||
                       osName.startsWith("Windows Me") ) {
                              return new
ProcessBuilder("command.com", "/C", commandLine);
                      }
                      return new ProcessBuilder("cmd.exe", "/C", commandLine);
              }
              return new ProcessBuilder("/bin/sh", "-c", commandLine);
      }

======================================================================
This method can be improved with more specific code depending on OS.




And a "system()" method with a behavior really equivalent to the
standard C library function system(), like this :

======================================================================

      /**
       * Executes a command specified in 'commandLine' by calling
       * the OS shell program, and returns after the command has been
completed.
       * @param commandLine The command-line to execute, using OS shell.
       * @return the exit value of the subprocess
       */
      public static int system(String commandLine) throws IOException,
InterruptedException {
              final Process process =
createShellFor(commandLine).inheritIO().start();
              try {
                      return process.waitFor();
              } finally {
                      process.destroy();
              }
      }

======================================================================

So, more complex and specific command-line can be used directly, like
in lots of others languages...


Thanks for reading,
Fred