Wednesday, July 14, 2021

How to execute native shell commands from Java Program? Example

How to execute native shell commands from JAVA
Though it’s not recommended some time it’s become necessary to execute a native operating system or shell command from Java, especially if you are doing some kind of reporting or monitoring stuff and required information can easily be found using the native command. This is not advised though because then you will lose platform independence which is why we mostly used Java.

Anyway, if you have no choice and you want to execute native commands from JAVA then it's good to know that how we can do it, many of you probably know this but for those who don't know and have never done it, we will see through an example.


Suppose you want to execute the "ls" command in Linux which lists down all the files and directories in a folder and you want to do it using JAVA.

In Java we have a class called "java.lang.Runtime" which is used to interact with the Runtime system has the facility to execute any shell command using method exec().

How to execute native shell commands from Java Program? Example



Here is the code sample which can be used to execute any native command from JAVA.

final String cmd = "ls -lrt";

int pid = -1;

try {
    // Run ls command
    Process process = Runtime.getRuntime().exec(cmd);
} catch (Exception e) {
    e.printStackTrace(System.err);
}
This is a little nice tip that can be very handy in some specific situations but by and large it's not advised by the very own reason of making JAVA code platform dependent.



as pointed out by Jaroslav sedlacek If not done properly it can easily hang the application. Java and external process communicate through buffers. If the buffer fills up, the external process stops and waits until java empties the buffer. Java app has to read both output and error streams of the process to prevent this blocking. There is good util class ProcessBuilder since 1.5 in java or apache commons exec can be used too. 


7 comments :

Jaroslav Sedlacek said...

I agree that executing external processes from Java should be used only exceptionally. It does not only create platform dependency but it is a potential minefield. If not done properly it can easily hang the application. Java and external process communicate through buffers. If buffer fills up, the external process stops and waits until java empties the buffer. Java app has to read both output and error streams of the process to prevent this blocking.
There is good util class ProcessBuilder since 1.5 in java or apache commons exec can be used too.

Javin @ FIX Protocol Tutorials said...

Thank you very much Jaroslav for your valuable comments and highlight the fact that Java and external process communicate through buffers and programmer needs to clear both output and error streams to prevent blocking.

Once again thank your for adding value into blog.

Javin

Unknown said...

Android developers can make great use of this for running native code on Android devices.Beware though, the executable can only be executed from the application locally permitted application directory : /data/data/app-package-here . cheers :)

Anonymous said...

I tried this example but no result ,
can someone help me please ,t want to execute a shell command in java

Javin @ String vs Stringbuffer said...

Hi Anonymous, Can you put more details why you are not able to execute any command from shell ? are you trying in windows or unix ? by the way this is the standard way of executing any shell command from java program. Please provide more details about your issue and we can help you better.

Unknown said...

I want to push arguments in the java File How can I do that.
Suppose, My routine is,

protected void executeCommand (String cmd) {

if (cmd == null) return ;

try {

System.out.println (cmd) ;

Process process = Runtime.getRuntime().exec (cmd);

try {

process.waitFor();

} catch (InterruptedException e) {

e.printStackTrace();

}

} catch (IOException ioe) {

ioe.printStackTrace();

}

}

And I want to run this,
java -Djava.library.path=. ArbitSocketGUI 1 2 3
as cmd in the routine.

And I want to access 1 2 3 in the ArbitSocketGUI Class. But I am unable to do that. Help me. How can I do that.

Anonymous said...

Java 9 is coming with new Process API, where creating and managing Process would be much easier as shown below:

String cmdArray = "ls -lrt";
System.out.println("Running a java process with PID " + ProcessHandle.current().getPid()+ ". Parent: " + ProcessHandle.current().parent().get().getPid());

Process pr = Runtime.getRuntime().exec(cmdArray);

System.out.println("Create Process with PID "+pr.getPid());

Post a Comment