C system() equivalent method.
Martin Buchholz
martinrb at google.com
Thu Oct 15 17:59:09 UTC 2009
Hi Frédéric,
Thanks for your suggestion.
The JDK has long had a culture of pushing people
to write portable code, and so any facility that would make
it easier to interact with the operating system in a non-portable way
meets resistance.
Another issue is that the "default" C system shell tends to
become dated over time - there are often better command interpreters.
Nevertheless, the existence of C "system" and the
"shell" keyword arg to python's subprocess.Popen are strong arguments
that the concept of a default shell is entrenched in the
programmer community.
Therefore, I support this proposal in principle.
Would someone at Sun like to sponsor this API change?
The spec probably needs a bit more work, so that readers
will know that we're talking about e.g. /bin/sh without
making that explicit.
Martin
2009/9/17 Frédéric Martini <frederic.martini at gmail.com>:
> 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
>
More information about the core-libs-dev
mailing list