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
Tags :

About the Author

mkyong
Founder of Mkyong.com and HostingCompass.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

  • John

    You can also use

    ProcessBuilder pb = new ProcessBuilder(computeCommandLine());
    pb.directory(workingDirectory);
     
    Map&lt;String, String&gt; env = pb.environment();
    env.put(&quot;VAR1&quot;, &quot;myValue&quot;);
    env.remove(&quot;OTHERVAR&quot;);
    env.put(&quot;VAR2&quot;, env.get(&quot;VAR1&quot;) + &quot;suffix&quot;);
     
    Process p = pb.start();
    ...
  • 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

    • http://www.mkyong.com mkyong

      “host” is a command available in most *nix systems. Make sure your system has installed it.

      • Dele

        I have a similar error. I ran it on windows 7 and got same erroe message.
        How, sir, can I resolve the problem?

        ERROR:

        java.io.IOException: Cannot run program “host”: CreateProcess error=2, The system cannot find the file specified
        at java.lang.ProcessBuilder.start(ProcessBuilder.java:459)
        at java.lang.Runtime.exec(Runtime.java:593)
        at java.lang.Runtime.exec(Runtime.java:431)
        at java.lang.Runtime.exec(Runtime.java:328)
        at javaClasses.ExecuteShellCommand.main(ExecuteShellCommand.java:37)
        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:81)
        at java.lang.ProcessImpl.start(ProcessImpl.java:30)
        at java.lang.ProcessBuilder.start(ProcessBuilder.java:452)
        … 4 more
        BUILD SUCCESSFUL (total time: 2 seconds)

  • 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 the c++ dll i’m getting the above error. I am unable to think why am i getting this error. the dll consists of code which generates a graphical window. mkyong plz help me in this issue…

    Thanks
    Raghavendra

    • 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 header file and using it instead of creating and destroying strings in functions eliminated an intermittent bug reported from the Window’s ntdll.dll.