How to execute shell command from Java

java-execute-shell-command

In Java, you can use Runtime.getRuntime().exec to execute external shell command :


    p = Runtime.getRuntime().exec("host -t a " + domain);
    p.waitFor();

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

    String line = "";			
    while ((line = reader.readLine())!= null) {
	sb.append(line + "\n");
    }

1. PING example

Classical example to execute the ping command and print out its output.

ExecuteShellComand.java

package com.mkyong.shell;

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

public class ExecuteShellComand {

	public static void main(String[] args) {

		ExecuteShellComand obj = new ExecuteShellComand();

		String domainName = "google.com";
		
		//in mac oxs
		String command = "ping -c 3 " + domainName;
		
		//in windows
		//String command = "ping -n 3 " + domainName;
		
		String output = obj.executeCommand(command);

		System.out.println(output);

	}

	private String executeCommand(String command) {

		StringBuffer output = new StringBuffer();

		Process p;
		try {
			p = Runtime.getRuntime().exec(command);
			p.waitFor();
			BufferedReader reader = 
                            new BufferedReader(new InputStreamReader(p.getInputStream()));

                        String line = "";			
			while ((line = reader.readLine())!= null) {
				output.append(line + "\n");
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		return output.toString();

	}

}

Output


PING google.com (74.125.135.x): 56 data bytes
64 bytes from 74.125.135.x: icmp_seq=0 ttl=53 time=8.289 ms
64 bytes from 74.125.135.x: icmp_seq=1 ttl=53 time=7.733 ms
64 bytes from 74.125.135.x: icmp_seq=2 ttl=53 time=8.343 ms

--- google.com ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 7.733/8.122/8.343/0.276 ms
null

2. HOST Example

Example to execute shell command host -t a google.com to get all the IP addresses that attached to google.com. Later, we use regular expression to grab all the IP addresses and display it.

P.S “host” command is available in *nix system only.

ExecuteShellComand.java

package com.mkyong.shell;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ExecuteShellComand {

	private static final String IPADDRESS_PATTERN = "([01]?\\d\\d?|2[0-4]\\d|25[0-5])" 
		+ "\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])" 
		+ "\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])" 
		+ "\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])";

	private static Pattern pattern = Pattern.compile(IPADDRESS_PATTERN);
	private static Matcher matcher;

	public static void main(String[] args) {

		ExecuteShellComand obj = new ExecuteShellComand();

		String domainName = "google.com";
		String command = "host -t a " + domainName;
		
		String output = obj.executeCommand(command);

		//System.out.println(output);
		
		List<String> list = obj.getIpAddress(output);

		if (list.size() > 0) {
			System.out.printf("%s has address : %n", domainName);
			for (String ip : list) {
				System.out.println(ip);
			}
		} else {
			System.out.printf("%s has NO address. %n", domainName);
		}

	}

	private String executeCommand(String command) {

		StringBuffer output = new StringBuffer();

		Process p;
		try {
			p = Runtime.getRuntime().exec(command);
			p.waitFor();
			BufferedReader reader = 
                           new BufferedReader(new InputStreamReader(p.getInputStream()));

			String line = "";			
			while ((line = reader.readLine())!= null) {
				output.append(line + "\n");
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		return output.toString();

	}

	public List<String> getIpAddress(String msg) {

		List<String> ipList = new ArrayList<String>();

		if (msg == null || msg.equals(""))
			return ipList;

		matcher = pattern.matcher(msg);
		while (matcher.find()) {
			ipList.add(matcher.group(0));
		}

		return ipList;
	}
}

Output


google.com has address : 
74.125.135.x
74.125.135.x
74.125.135.x
74.125.135.x
74.125.135.x
74.125.135.x

References

  1. Runtime.getRuntime().exec JavaDoc
  2. How To Validate IP Address With Regular Expression

About the Author

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

Comments

Leave a Reply

avatar
newest oldest most voted
John
Guest
John

You can also use

ProcessBuilder pb = new ProcessBuilder(computeCommandLine());
pb.directory(workingDirectory);
			
Map<String, String> env = pb.environment();
env.put("VAR1", "myValue");
env.remove("OTHERVAR");
env.put("VAR2", env.get("VAR1") + "suffix");
			
Process p = pb.start();
...
Zanidd
Guest
Zanidd

I used the same (similar) code for my ShellWrapper. When I use commands like echo it works fine, but when I use commands like cat it returns an empty String….

Edy B
Guest
Edy B

As a good practice, I wouldn’t catch Exception e. Just mention the two that need to be dealt with (IOException, InterruptedException) .

Brian J. M. Rogers
Guest
Brian J. M. Rogers

Where do I download the shell package?

Ganesh Neelekani
Guest
Ganesh Neelekani

I am trying to convert avro to json file through java, But it is not working
String output = obj.executeCommand(“java -jar /Users/xyz/Desktop/1server/jboss-as-7.1.1.Final/standalone/deployments/Command.war/WEB-INF/lib/avro-tools-1.7.7.jar tojson /Users/xyz/Desktop/avro/4.avro > /Users/xyz/Desktop/avro/D8EC9CC2A3E049648AFD4309B29D2A0F/4.json”);
But this is not working through java file,

I ran same command through terminal, avro is converted to json

Can you help me to run “java -jar * ” command

Jayanth Sanganabhatla
Guest
Jayanth Sanganabhatla

let’s say we type ‘mysql’ in command prompt.

c:mysql
then the prompt changes to:
mysql>
now in this we type sql commands.
Can we achieve/automate this with java?

???????
Guest
???????

mysql [ARGS] < SCRIPT and you're done. No need to fall into the interactive shell.

Yehia Azanki
Guest
Yehia Azanki

Why commands with pattern don’t work? Example: uptime | sed “s/^.* up \+\(.\+\), \+[0-9] user.*$/\1/”

Stephane
Guest
Stephane

The article would be even better with a note on how to run a shell file sitting in the resources directory.
Thanks for the jump start anyway !

pk
Guest
pk

I really like your articles on Java. For this one i guess i could not do as mentioned. I googled and figured out that you need to first connect to the linux box from java and then you can execute shell commands. I could not make the Linux commands run from Java which is on Windows using this code.

vishal
Guest
vishal

Hi How can we add Timeout ?

GD
Guest
GD

If I want to check my java version on Mac, I used the “PING” example and replaced the command string with my value i.e. String command = “java -version”;
but the command does not get executed at all. Can you please let me know what am I missing?

can
Guest
can

GOOOOOD

ug
Guest
ug

Mkyong your tutorials are always straight to the point, bravo.

S Philip
Guest
S Philip

Hi I am trying to create a Terminal Emulator for Linux using Java… Can you help me by giving a direction..

Thanks in advance…

Guest
Guest
Guest

Access denied. Option -c requires administrative privileges. —-how to fix admin issue on windows 8.1

Guest
Guest
Guest

ok i got it had to read -n yea, thanks

Hong Junho
Guest
Hong Junho

Using array parameter is better, because…when some parameter has blank ( ex. “ABC DE” ) it will be treated as 2 parameters…

Array parameter is more safe… :)

Sorry…english is not my mother tongue…

Adam Outler
Guest
Adam Outler
The following code allows you to set a timer, restart the timer on keywords, and specify if you want it to be sent to your log or not. This prevents several problems I’ve run into while programming on the command line. The method is complex, very complex, but it works well and avoids loops in favor of waiting for a synchronized notification whenever possible. It uses three threads. The main thread launches the application and waits. The reader thread processes whatever comes out of the application. The watchdog thread monitors for timeout and gets kicked by the reader thread to… Read more »
_mrdoob_
Guest
_mrdoob_

Classic vulnerability :)

Sriram Ganesh
Guest
Sriram Ganesh

Thanks a lot for another excellent tutorial Mr.Yong. The most reliable website…!!

gorki
Guest
gorki

Please help me…
java.io.IOException: Cannot run program “host”: CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
at java.lang.Runtime.exec(Runtime.java:615)
at java.lang.Runtime.exec(Runtime.java:448)
at java.lang.Runtime.exec(Runtime.java:345)
at com.levanlong.demo.file.inputstream.IpAddress.main(IpAddress.java:34)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.(ProcessImpl.java:188)
at java.lang.ProcessImpl.start(ProcessImpl.java:132)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1021)
… 4 more

raghavendra
Guest
raghavendra
# # A fatal error has been detected by the Java Runtime Environment: # # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x10038859, pid=4248, tid=204 # # JRE version: 6.0_18-b07 # Java VM: Java HotSpot(TM) Client VM (16.0-b13 mixed mode, sharing windows-x86 ) # Problematic frame: # C [mpe.dll+0x38859] # # An error report file with more information is saved as: # C:\Users\workspace\EJBWS\DLLSTest\hs_err_pid4248.log # # If you would like to submit a bug report, please visit: # http://java.sun.com/webapps/bugreport/crash.jsp # The crash happened outside the Java Virtual Machine in native code. # See problematic frame for where to report the bug. # when i’m executing… Read more »
raymond jones
Guest
raymond jones
Suggestion to try displaying a very simple message box first in dll in order to determine if you gui has the error and not the code. If this works, then the problem is in your graphical window and not the dll or java. Try this: // buffer256 is declared in header file or cpp file. static char buffer256[256]; // Generic buffer // put code below in function in cpp file. strcpy_s(buffer256, 256, “You are in C++ dll.”); ::MessageBoxA(NULL, buffer256, “Message from MyDll.dll”, 0); Tip: when working with strings in dll’s, I found that using a char buffer declared in a… Read more »
Michael
Guest
Michael

The Process.waitFor() statement should instead be invoked after the BufferedReader finishes reading the input stream of the Process. This fixes an issue I am having here: the program stucks and never returns but the actual command in my Mac Terminal exits within a second.

Another tip is that it is better to use Process.waitFor(long, TimeUnit) to prevent that the Java program hangs.

Michael
Guest
Michael

As an additional remark, using Process.waitFor(long, TimeUnit) isn’t the complete solution. In my case, the command never returns and it does not print anything in Terminal.
In this case, the BufferedReader.readLine() causes the program to hang. It seems that adding an if condition to check BufferedReader.ready() before BufferedRader.readLine() can solve the issue.

Michael
Guest
Michael

I also find that I will need to have Process.waitFor() statement invoked BEFORE the BufferedReader reads the input stream of the Process if I have BufferedReader.ready() added.

Nilesh
Guest
Nilesh

Hello,

I want to execute 2 commands in a sequence.
1. cd D://
2. java -jar -role hub

I tried below code but it tries to execute jar file first and then cd :

ProcessBuilder builder = new ProcessBuilder(“cmd”,”/c”,”start”,”cmd.exe”,”/K”, “java -jar -role hub && cd \”D:\\””);
builder.redirectErrorStream(true);
Process p = builder.start();

any suggestion for first cd should get execute and then .jar?

Nilesh
Guest
Nilesh

please read D://foldername and java -jar jarFile