Main Tutorials

Java ProcessBuilder examples

In Java, we can use ProcessBuilder to call external commands easily :


	ProcessBuilder processBuilder = new ProcessBuilder();

	// -- Linux --

	// Run a shell command
	processBuilder.command("bash", "-c", "ls /home/mkyong/");

	// Run a shell script
	processBuilder.command("path/to/hello.sh");

	// -- Windows --

	// Run a command
	processBuilder.command("cmd.exe", "/c", "dir C:\\Users\\mkyong");

	// Run a bat file
	processBuilder.command("C:\\Users\\mkyong\\hello.bat");

	Process process = processBuilder.start();

1. Ping

1.1 Run an external ping command to ping a website 3 times, and display the output.

ProcessBuilderExample1.java

package com.mkyong.process;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ProcessBuilderExample1 {

    public static void main(String[] args) {

        ProcessBuilder processBuilder = new ProcessBuilder();

        // Run this on Windows, cmd, /c = terminate after this run
        processBuilder.command("cmd.exe", "/c", "ping -n 3 google.com");

        try {

            Process process = processBuilder.start();

			// blocked :(
            BufferedReader reader =
                    new BufferedReader(new InputStreamReader(process.getInputStream()));

            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }

            int exitCode = process.waitFor();
            System.out.println("\nExited with error code : " + exitCode);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

}

Output


Pinging google.com [172.217.166.142] with 32 bytes of data:
Reply from 172.217.166.142: bytes=32 time=10ms TTL=55
Reply from 172.217.166.142: bytes=32 time=10ms TTL=55
Reply from 172.217.166.142: bytes=32 time=10ms TTL=55

Ping statistics for 172.217.166.142:
    Packets: Sent = 3, Received = 3, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 10ms, Maximum = 10ms, Average = 10ms

Exited with error code : 0

2. Ping + Thread

In above example 1.1, the process.getInputStream is “blocking”, it is better to start a new Thread for the reading process, so that it won’t block other tasks.

ProcessBuilderExample2.java

package com.mkyong.process;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;

public class ProcessBuilderExample2 {

    public static void main(String[] args) {

        ExecutorService pool = Executors.newSingleThreadExecutor();

        ProcessBuilder processBuilder = new ProcessBuilder();

        // Run this on Windows, cmd, /c = terminate after this run
        processBuilder.command("cmd.exe", "/c", "ping -n 3 google.com");

        try {

            Process process = processBuilder.start();

            System.out.println("process ping...");
            ProcessReadTask task = new ProcessReadTask(process.getInputStream());
            Future<list<string>> future = pool.submit(task);

            // no block, can do other tasks here
            System.out.println("process task1...");
            System.out.println("process task2...");

            List<string> result = future.get(5, TimeUnit.SECONDS);
            for (String s : result) {
                System.out.println(s);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            pool.shutdown();
        }
    }

    private static class ProcessReadTask implements Callable<list<string>> {

        private InputStream inputStream;

        public ProcessReadTask(InputStream inputStream) {
            this.inputStream = inputStream;
        }

        @Override
        public List<string> call() {
            return new BufferedReader(new InputStreamReader(inputStream))
				.lines()
				.collect(Collectors.toList());
        }
    }

}

Output


process ping...
process task1...
process task2...

Pinging google.com [172.217.166.142] with 32 bytes of data:
Reply from 172.217.166.142: bytes=32 time=11ms TTL=55
Reply from 172.217.166.142: bytes=32 time=10ms TTL=55
Reply from 172.217.166.142: bytes=32 time=10ms TTL=55

Ping statistics for 172.217.166.142:
    Packets: Sent = 3, Received = 3, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 10ms, Maximum = 11ms, Average = 10ms

3. Change Directory

3.1 Change to directory C:\\users and run external dir command to list out all the files.

ProcessBuilderExample3.java

package com.mkyong.process;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;

public class ProcessBuilderExample3 {

    public static void main(String[] args) {

        ProcessBuilder processBuilder = new ProcessBuilder();

        processBuilder.command("cmd.exe", "/c", "dir");
        processBuilder.directory(new File("C:\\users"));

        // can also run the java file like this
        // processBuilder.command("java", "Hello");

        try {

            Process process = processBuilder.start();

            BufferedReader reader =
                    new BufferedReader(new InputStreamReader(process.getInputStream()));

            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }

            int exitCode = process.waitFor();
            System.out.println("\nExited with error code : " + exitCode);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

}

Output


 Volume in drive C has no label.
 Volume Serial Number is CE5B-B4C5

 Directory of C:\users

//...

References

  1. Microsoft System Error Codes (0-499)
  2. How to execute shell command from Java
  3. Java docs – ProcessBuilder
  4. What does cmd /C mean?

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
11 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Evan Yang
2 years ago

Hi:
Thanks so much for you helpful post:)
May I ask several questions:

  1. When should I call Process.destroy()? Is it after waitFor()?
  2. What if I use waitFor(timeout, timeUnit) instead of waitFor()? Should I also call Process.destroy() after waitFor(timeout, timeUnit)?

Thanks again 🙂

vishal
2 years ago
Reply to  Evan Yang
If you are using single thread process.waitFor()?
current Thread block unit Destroy the process

if you are using multiThread when process.destroy()

process immediately destroy

i hope this help your doubt
Sreecharan Shroff
2 years ago

Hi,

could you please let me know if there is an existing OpenSource Java library which creates OS based tasks (task scheduler on windows, crontab on linux), reads the task execution history ?
something similar to this Java API (this is not a finished project)
https://github.com/martinodutto/windows-task-scheduler-api

Thanks,
Charan

Anda
3 years ago

Hello,

How can combine dos commands with Linux commands?

So, I need to run git-bash command and then a Linux command and to store the result into a file.

Fahad
3 years ago

Hi, I have some questions .I have written a shell script which connects to oracle database and performs operation and returns some output message. Script works fine from command prompt.

But my problem is , the shell script takes nearly 1 hour or less or even more to do its job in the database and untill then my console keeps showing as busy. Whereas in command prompt, shell script displays messages as it runs and thus keeps the end user informed about its progress. However, when called from java it waits untill the shell script completes/terminates and finally displays all the messages at once. I want to know if there is a way to display the shell script output as it continues to run in the background ( child process ).

gourav
4 years ago

hi, Can we execute kubectl commands through java?

JGFMK
4 years ago

Very useful. You do have the odd mistake. list -> List or string -> String. But helped me a great deal. Cheers

minu
4 years ago

How i update a file in linux
in linux use vi filename-> press key i-> go to the line where modification is required -> update the value -> esc -> :wq
how to do these commands in java and how to go to the particular line which needs modification?

Marty
4 years ago

In Eclipse, I get an error with the code below. Type mismatch: cannot convert from List to List

@Override
public List call() {
return new BufferedReader(new InputStreamReader(inputStream))
.lines()
.collect(Collectors.toList());
}

Rajaram chelledurai
4 years ago

how to run a batch file with arguments using ProcessBuilder

Todd
5 years ago

Minor typo in code: <list> should be <List>