1

I have one shell script which has some commands, one of which command is expecting to enter some data at runtime. I am running this shell script using exec() method. Currently I am entering data manually if it asks to enter. Following is my code,

            Process p = Runtime.getRuntime().exec("myshellscript");

            BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));

            BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));

            // read the output from the command
            System.out.println("Here is the standard output of the command:\n");
            while ((s = stdInput.readLine()) != null) {
                System.out.println(s);
            }

           // read any errors from the attempted command
            System.out.println("Here is the standard error of the command (if any):\n");
            while ((s = stdError.readLine()) != null) {
                System.out.println(s);
            }

            System.exit(0);

What I want to do is whenever console expect's data to be entered, it should be entered by java program and just continue my further java program.

1 Answer 1

2

Here's what I do:

  1. create two threads that will read from p.getInputStream() and p.getErrorStream(),
  2. write the data in p.getOutputStream(),
  3. wait for the two thread to terminate (with the join() method)

EDIT:

public class Main {
    private static final Logger LOG = Logger.getLogger(Main.class.getName());

    public static void main(String[] args) {
        try {
            Process p = Runtime.getRuntime().exec("myshellscript");
            Thread outHandler = new OutputHandler(p.getInputStream(), "UTF-8");
            outHandler.setDaemon(true);
            outHandler.start();
            Thread errHandler = new OutputHandler(p.getErrorStream(), "UTF-8");
            errHandler.setDaemon(true);
            errHandler.start();
            sendInput(p, "the input data", "UTF-8");
            int result = p.waitFor();
            outHandler.join();
            errHandler.join();
            System.out.println("exit code: " + result);
        } catch (IOException ex) {
            LOG.log(Level.SEVERE, null, ex);
        } catch (InterruptedException ex) {
            LOG.log(Level.SEVERE, null, ex);
        }
    }    

private void sendInput(Process process, String input, String encoding)
        throws IOException {

    try (OutputStream stream = process.getOutputStream();
            Writer writer = new OutputStreamWriter(
                    stream, encoding == null ? "UTF-8" : encoding);
            PrintWriter out = new PrintWriter(writer)) {
        if (input != null) {
            Reader reader = new StringReader(input);
            BufferedReader in = new BufferedReader(reader);
            String line = in.readLine();
            while (line != null) {
                out.println(line);
                line = in.readLine();
            }
        }
    }
}

    private static class OutputHandler extends Thread {
        private BufferedReader in;

        private OutputHandler(InputStream in, String encoding)
                throws UnsupportedEncodingException {
            this.in = new BufferedReader(new InputStreamReader(
                    in, encoding == null ? "UTF-8" : encoding));
        }

        @Override
        public void run() {
            try {
                String s = in.readLine();
                while (s != null) {
                    System.out.println(s);
                    s = in.readLine();
                }
            } catch (IOException ex) {
                LOG.log(Level.SEVERE, null, ex);
            } finally {
                try {
                    in.close();
                } catch (IOException ex) {
                    LOG.log(Level.SEVERE, null, ex);
                }
            }
        }
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

can you please brief the code I am new to java, I never worked on multithreading.
Note that if you were using a ProcessBuilder, you could do redirectErrorStream(true) and you would need only one thread.
Added method sendInput
Thank you so much for your wonderful help Maurice Perry, I was struggling on it for long time now it worked.

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.