0

Normally I use this code to run a bash script and get it's output

ProcessBuilder pb = new ProcessBuilder("/home/myscript");
Process p = pb.start();
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
String inputRead;
p.waitFor();
while((inputRead=stdInput.readLine()) != null){
    Helper.log(inputRead);
}

This works fine but this time the bash script I am using didn't terminate. It's always active and when it detect something it print it. I want to start the script, wait for some time and than check if it detected something. I tried to use p.wait(periode); I tried this code

p.wait(10000);
while((inputRead=stdInput.readLine()) != null){
    Helper.log(inputRead);
}

I am not sure if it's the right solution for my problem but anyway I get an error with this code

java.lang.IllegalMonitorStateException

My question is not really about waiting, but how to stop the process after waiting and still be able to get the output.

4
  • Usually, IllegalMonitorStateException means that a thread is trying to wait/notify an object monitor without owning it. Make sure no threads are trying to do that. Commented Oct 17, 2016 at 14:23
  • I see what you're doing. p.wait() needs to be inside a synchronized statement: docs.oracle.com/javase/tutorial/essential/concurrency/…. If you want the thread to wait, use Thread.sleep(). Commented Oct 17, 2016 at 14:25
  • The script "/home/myscript" write to a file? Commented Oct 17, 2016 at 14:27
  • What makes you think that calling Object.wait() on the Process object is a good idea? It's not - that method has a totally different purpose, and has the precondition that you need to hold the monitor on the object (synchronize on it). But that's not the fix for your problem. Commented Oct 17, 2016 at 14:30

2 Answers 2

0

In your case using .wait(1000), is totally wrong. That's what the exception also tells you.
Exactly for your usecase there's waitFor(long timeout, TimeUnit unit):

p.waitFor(10, TimeUnit.SECONDS);
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you but I used your code and the threat never terminated. Maybe I should destroy the process after this code ? But as I said, if I destroy it I am not able to get the output anymore
Did you remove the while loop after using my proposal?
No but the while loop is just for logging the input generated from the script. And the script never stops because I still have the input logged for ever
0

Below is the complete example of the solution. A separate thread switches a flag for the main thread to terminate and then output the collected lines:

private static boolean triggerToClose = false;

  public static void main(String[] args) throws IOException,
      InterruptedException {
    ProcessBuilder pb =
        new ProcessBuilder("/home/myscript");
    Process p = pb.start();
    java.io.InputStream is = p.getInputStream();
    BufferedReader stdInput = new BufferedReader(new InputStreamReader(is));
    String inputRead;
    new Thread(new Runnable() {
      public void run() {
        try {
          Thread.sleep(10000);
        } catch (InterruptedException e) {
        }
        triggerToClose = true;
      }
    }).start();
    StringBuilder sb = new StringBuilder();
    while ((inputRead = stdInput.readLine()) != null) {
      if (triggerToClose) {
        p.destroy();
        break;
      }

      sb.append(inputRead).append('\n');
    }
    System.out.println(sb);
  }

5 Comments

If i use this command the threat will never terminate. If i use p.destroy(); after your code I will not be able to get the output result, I got the message java.io.IOException: Stream closed
The sleep() command shouldn't keep the current thread running for more than the time specified as an argument. Are you sure that the process started by /home/myscript really terminates?
No the process /home/myscript never terminate this is the problem. I just want to run the script for a short period of time, in this example 10 seconds then stop it and get the output generated by the script in this period.
The answer is updated

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.