public class LinuxInteractor {
public static String executeCommand(String command)
{
System.out.println("Linux command: " + command);
try
{
Process p = Runtime.getRuntime().exec(command);
p.waitFor();
BufferedReader bf=new BufferedReader(new InputStreamReader( p.getInputStream()));
String str=bf.readLine();
System.out.println("inputStream is::"+str);
while( (str=bf.readLine()) != null)
{
System.out.println("input stream is::"+str);
}
System.out.println("process started");
}
catch (Exception e) {
System.out.println("Error occured while executing Linux command. Error Description: "
+ e.getMessage());
e.printStackTrace();
}
}
When I run the script through console, it's working. But through Java program InputStream(Str)
is coming as null
.
Is there any other approach I can use?
Solution
You should try to do the reading and the executing on different threads.
A better alternative is to use a ProcessBuilder, which takes care of the "dirty" work for you.
The code inside the try
block could look something like this:
/* Create the ProcessBuilder */
ProcessBuilder pb = new ProcessBuilder(commandArr);
pb.redirectErrorStream(true);
/* Start the process */
Process proc = pb.start();
System.out.println("Process started !");
/* Read the process's output */
String line;
BufferedReader in = new BufferedReader(new InputStreamReader(
proc.getInputStream()));
while ((line = in.readLine()) != null) {
System.out.println(line);
}
/* Clean-up */
proc.destroy();
System.out.println("Process ended !");
See, also, this short demo.
Cause of the problem
According to the Java Docs, waitFor()
:
causes the current thread to wait, if necessary, until the process represented by this Process object has terminated.
So, you are trying to get the process's output-stream after it has terminated, therefore the null
.
(Sorry for the major revamp of the answer.)
You need to do this in a separate thread:
Process process = Runtime.getRuntime().exec(command);
LogStreamReader lsr = new LogStreamReader(process.getInputStream());
Thread thread = new Thread(lsr, "LogStreamReader");
thread.start();
public class LogStreamReader implements Runnable {
private BufferedReader reader;
public LogStreamReader(InputStream is) {
this.reader = new BufferedReader(new InputStreamReader(is));
}
public void run() {
try {
String line = reader.readLine();
while (line != null) {
System.out.println(line);
line = reader.readLine();
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Then you need a second thread for input handling. And you might want to deal with stderr just like stdout.