Executing Operating System Commands From Java

See my other post Piping Between Processes for piping data between two or more processes.

There are two ways to start an operating system process within Java:

Getting Started

To execute an operating system command from a Java program, use:

java.lang.Runtime.getRuntime().exec("a-command");

A more complete example:

public class ShellTest {
    public static void main(String[] args) throws java.io.IOException, java.lang.InterruptedException {
        // Get runtime
        java.lang.Runtime rt = java.lang.Runtime.getRuntime();
        // Start a new process: UNIX command ls
        java.lang.Process p = rt.exec("ls");
        // Show exit code of process
        System.out.println("Process exited with code = " + rt.exitValue());
    }
}

ProcessBuilder

Another way since Java 5 is to use java.lang.ProcessBuilder. Think of it as a template to start new processes. Create one ProcessBuilder per command you want to invoke:

public class ShellTest {
    public static void main(String[] args) throws java.io.IOException, java.lang.InterruptedException {
        // Create ProcessBuilder instance for UNIX command ls -l
        java.lang.ProcessBuilder processBuilder = new java.lang.ProcessBuilder("ls", "-l");
        // Create an environment (shell variables)
        java.util.Map env = processBuilder.environment();
        env.clear();
        env.put("COLUMNS", "3"); // See manpage ls(1)
        // You can change the working directory
        pb.directory(new java.io.File("/Users"));
        // Start new process
        java.lang.Process p = pb.start();
    }
}

Submission of environment variables and a working directory is also possible with java.lang.Runtime#exec(java.lang.String[], java.lang.String[], java.io.File), look here.

Input and Output

If you need to get the output of a java.lang.Process, you can get a stream for its output, its java.io.InputStream:

public class ShellTest {
    public static void main(String[] args) throws java.io.IOException, java.lang.InterruptedException {
        // Get runtime
        java.lang.Runtime rt = java.lang.Runtime.getRuntime();
        // Start a new process: UNIX command ls
        java.lang.Process p = rt.exec("ls");
        // You can or maybe should wait for the process to complete
        p.waitFor();
        System.out.println("Process exited with code = " + rt.exitValue());
        // Get process' output: its InputStream
        java.io.InputStream is = p.getInputStream();
        java.io.BufferedReader reader = new java.io.BufferedReader(new InputStreamReader(is));
        // And print each line
        String s = null;
        while ((s = reader.readLine()) != null) {
            System.out.println(s);
        }
        is.close();
    }
}

You can send input to a process by writing to its java.io.OutputStream:

public class ShellTest {
    public static void main(String[] args) throws java.io.IOException, java.lang.InterruptedException {
        java.lang.Runtime rt = java.lang.Runtime.getRuntime();
        java.lang.Process p = rt.exec("ls");
        p.waitFor();
        System.out.println("Process exited with code = " + rt.exitValue());
        // Get process' input: its OutputStream
        java.io.OutputStream os = p.getOutputStream();
        os.write("my input".getBytes());
        os.close();
    }
}

In Groovy this is — as usual — a bit shorter:

// Execute and wait for process
def p = "ls -l".execute()
p.waitFor()
// Get output from process
println p.text

Resources

This entry was posted in Software Development and tagged . Bookmark the permalink.