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?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
SachG
  • 105
  • 1
  • 2
  • 12
  • 1
    1) Read (and implement) *all* the recommendations of [When Runtime.exec() won't](http://www.javaworld.com/jw-12-2000/jw-1229-traps.html). 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. – Andrew Thompson Jun 11 '13 at 07: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. – user207421 Jun 11 '13 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. – SachG Jun 11 '13 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()`? – user207421 Jun 12 '13 at 08:55

2 Answers2

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

gkalpak
  • 47,844
  • 8
  • 105
  • 118
  • Anything starting with 'try' is a good candidate for a comment, and a bad candidate for an answer. – Andrew Thompson Jun 11 '13 at 07:12
  • Without waitFor() and after process output ,i tried.but same problem comes.InputStream Stirng comes as null. – SachG Jun 11 '13 at 07:21
  • 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. – gkalpak Jun 11 '13 at 07:34
  • @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) ;) – gkalpak Jun 11 '13 at 08:37
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.

Juned Ahsan
  • 67,789
  • 12
  • 98
  • 136