4
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?

4
  • 1
    1) Read (and implement) all the recommendations of When Runtime.exec() won't. That might solve the problem. If not, it should provide more information as to the reason it failed. Then ignore that it refers to exec and build the Process using a ProcessBuilder. Also break a String arg into String[] args to account for arguments which themselves contain spaces. 2) I suspect the waitFor call should be after the stream consumption. Commented Jun 11, 2013 at 7:11
  • 1
    It's a bit pointless waiting for the process to exit before you read any of its output. If its output buffer fills it can never exit at all. There is no InputStream(Str) in your code, but if you are claiming that Process.getInputStream() returns null it's hard to believe that you are correct. Commented Jun 11, 2013 at 10:20
  • @EJP InputStream is=Process.getInputStream; if i read it through buffer-reader.its coming as null. its solved now,need to do it in another thread. Commented Jun 11, 2013 at 10:56
  • That doesn't make sense. Either the InputStream is null or it isn't. If it's null you can't 'read it through BufferedReader' at all. Do you mean you read a null with BufferedReader.readLine()? Commented Jun 12, 2013 at 8:55

2 Answers 2

8

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.)

Sign up to request clarification or add additional context in comments.

4 Comments

Anything starting with 'try' is a good candidate for a comment, and a bad candidate for an answer.
Without waitFor() and after process output ,i tried.but same problem comes.InputStream Stirng comes as null.
I know :) This answer is totaly wrong and will be deleted soon. I am just curious how many upvotes this wrong answer may get. Sorry for the trouble. You better read it in a separate thread as Juned Ahsan suggests.
@sachingrover: I know you have already solved your problem, but you might want to take a look at my updated answer for an alternative (it always a good thing to have more than one ways to solve a problem) ;)
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.