java shell
From Noah.org
Revision as of 11:36, 15 March 2010 by Root (talk | contribs) (Created page with 'Category: Engineering This shows how to call an external script from Java. This is intended for UNIX systems, but may work under other systems if you substitute a different …')
This shows how to call an external script from Java. This is intended for UNIX systems, but may work under other systems if you substitute a different shell or if you install CYGWIN.
import java.io.*; import java.util.*; public class shell { /** This tests the runBashShellCommand method. * The following are some examples of how it works: * * $ java shell echo Hello * 0 * Hello * * $ java shell "echo Hello; exit 1" * 1 * Hello * * $ java shell "echo Hello; exit 0" * 0 * Hello */ public static void main(String args[]) throws IOException, java.lang.InterruptedException { System.out.println (runBashShellCommand (args)); } /** This runs a command in a Bash shell and returns the output. * * For example, the following should print "hello": * * String [] args = {"foo=hello", ";", "echo", "$foo"}; * System.out.println (runBashShellCommand (args)); * * You may combine commands and arguments into a single string. * This is equivalent to the previous example: * * String [] args = {"foo=hello ; echo $foo"}; * System.out.println (runBashShellCommand (args)); * * This method will CLOSE the stdin of the subprocess so that it cannot * read from this filedescriptor. For example, the following should be * safe; Bash will simply set 'foo' to an empty string instead of blocking * on the 'read' call. * * String [] args = {"read", "foo", ";", "echo", "$foo"}; * System.out.println (runBashShellCommand (args)); * * Comments: This method is probably overkill. * * @author Noah Spurrier * @param args The first element should be the command to be run. * Additional elements should be arguments. * @return the output of the command as a String. The first line of the * string will be the exit code from the command that was run. * @throws IOException if there was a problem with the subshell. * @throws InterruptedException if the subshell was killed. */ public static String runBashShellCommand (String args[]) throws IOException, java.lang.InterruptedException { java.util.List<String> command_and_args = new java.util.ArrayList<String> (); command_and_args.add ("/bin/bash"); command_and_args.add ("-c"); StringBuffer cmd_string = new StringBuffer (); for (String arg : args) { cmd_string.append (arg).append (' '); } command_and_args.add (cmd_string.toString().trim()); // Start Bash and script. ProcessBuilder pb = new ProcessBuilder (command_and_args); pb.redirectErrorStream (true); Process process = pb.start (); ////////////////////////////////////////////////////////////////////// // WARNING: There is a race condition here. We want the subprocess to // have its stdin cutoff BEFORE it actually tries to read from stdin. // This is mainly to be proper; not to prevent any sort of dead-lock. // There is no danger that this will block us since the subprocess runs // asynchronously. This shouldn't be a big deal, but it should be // tested to be sure. -- Noah process.getOutputStream().close(); // Get output from the command. BufferedReader br = new BufferedReader (new InputStreamReader (process.getInputStream())); StringBuffer out = new StringBuffer (); String line = null; while ((line = br.readLine ()) != null) { out.append (line).append ('\n'); } // Wait for process to finish. int exit_code = process.waitFor(); out.insert (0, String.valueOf(exit_code) + "\n"); return out.toString(); } }