2
try {

        String str;
        Process process = Runtime.getRuntime().exec("bash /home/abhishek/workspace/Pro/run");
        InputStream isout = process.getInputStream();
        InputStreamReader isoutr = new InputStreamReader(isout);
        BufferedReader brout = new BufferedReader(isoutr);
        while ((str = brout.readLine()) != null) {
            System.out.println(str);
        }

} catch (IOException e) {
        e.printStackTrace();
}

The Code has issues with getting the InputStream from the Process, because if I run the Shell script from my Terminal it runs completely fine, but if I Run the Script like this,the str is always null,

I am using this code to get the output of the Shell Script directly into Java instead writing the Script Output in the File

Is there any other way to achieve this,or how can I get the issue solved using the current approach

4

6 に答える 6

6

I think something returned through the error stream, so you can try to check something from the Process.getErrorStream().

You should also wait for the created process to prevent your main program completes before it. Use Process.waitFor();

public class TestMain {
   private static final String BASH_CMD = "bash";

   private static final String PROG = "/home/abhishek/workspace/Pro/run";

   private static final String[] CMD_ARRAY = { BASH_CMD , PROG };

   public static void main(String[] args) {
      new Thread(new Runnable() {
         public void run() {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                  System.in));
            String command = null;
            try {
               while ((command = reader.readLine()) != null) {
                  System.out.println("Command Received:" + command);
               }
            } catch (Exception ex) {
               ex.printStackTrace();
               // failed to listening command
            }

         }
      }).start();
      Process process = null;
      try {
         ProcessBuilder processBuilder = new ProcessBuilder(CMD_ARRAY);
         process = processBuilder.start();
         InputStream inputStream = process.getInputStream();
         setUpStreamGobbler(inputStream, System.out);

         InputStream errorStream = process.getErrorStream();
         setUpStreamGobbler(errorStream, System.err);

         System.out.println("never returns");
         process.waitFor();
      } catch (IOException e) {
         throw new RuntimeException(e);
      } catch (InterruptedException e) {
         throw new RuntimeException(e);
      }
   }

   public static void setUpStreamGobbler(final InputStream is, final PrintStream ps) {
      final InputStreamReader streamReader = new InputStreamReader(is);
      new Thread(new Runnable() {
         public void run() {
            BufferedReader br = new BufferedReader(streamReader);
            String line = null;
            try {
               while ((line = br.readLine()) != null) {
                  ps.println("process stream: " + line);
               }
            } catch (IOException e) {
               e.printStackTrace();
            } finally {
               try {
                  br.close();
               } catch (IOException e) {
                  e.printStackTrace();
               }
            }
         }
      }).start();
   }
}
于 2013-02-07T06:47:55.040 に答える
0

Possible problem is by the time you obtain inputStram the sub-process is not ready

Try

Process process = Runtime.getRuntime().exec("bash /home/abhishek/workspace/Pro/run");
InputStream isout = process.getInputStream();    
process.waitFor()
于 2013-02-06T11:20:59.690 に答える
0

Edit you /home/abhishek/workspace/Pro/run if it is a shell and add the following line on top.

#!/usr/bin/bash

and give required execute permissions to /home/abhishek/workspace/Pro/run.

Then use the following line

Process process = Runtime.getRuntime().exec("/home/abhishek/workspace/Pro/run");

Now if the run program prints anything you should see it in the output.

于 2013-02-06T11:21:32.950 に答える
0

Your code looks fine. So, I believe that problem is either in command line you are using (bash /home/abhishek/workspace/Pro/run) or in your script itself.

I'd suggest you to perform the following steps:

  1. try to run some well-known command instead of your script. For example pwd. Check that your code that is reading from input stream works correctly.
  2. Now try to simplify your script. Create script run1 that just runs the same pwd. Now run this script from java and see that it is working. BTW you do not have to run it as bash yourscript. You can directly run it without bash prefix
  3. If all this works start to move from simple to your real script step-by-step. I believe you will find your mistake. Probably your script cannot start for some environment related problems.
于 2013-02-06T11:24:07.087 に答える
0

Try something like this:

String[] runCommand = new String[3];

runCommand[0] = "sh";
runCommand[1] = "-c";
runCommand[2] = "bash /home/abhishek/workspace/Pro/run";

Process process = runtime.exec(runCommand);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = reader.readLine();
reader.close();
于 2013-02-06T11:43:30.603 に答える
0

After multiple readings of the source code for the unix implementation of Process at https://github.com/AdoptOpenJDK/openjdk-jdk11/blob/master/src/java.base/unix/classes/java/lang/ProcessImpl.java it seems that the standard redirects will always swallow to a ProcessBuilder.NullInputStream:

    if (redirects[1] == Redirect.PIPE) {
        std_fds[1] = -1;
    }...

and

    stdout = (fds[1] == -1 || forceNullOutputStream) ?
            ProcessBuilder.NullInputStream.INSTANCE :
            new ProcessPipeInputStream(fds[1]);

(The same code repeats for stdIn, stdOut and stdErr streams)

The only workaround I have found, which feels very clumsy is to use a temp File:

    File stdOutTmp;  // create and destroy however you see fit
    ProcessBuilder pb = ...;
    pb.redirectOutput(ProcessBuilder.Redirect.to(stdOutTmp));
    ...

There are other static factory methods (Redirect.appendTo(File) to append to an existing file rather than overwrite an existing file, and Redirect.from(File) for stdIn)

于 2021-11-09T18:32:21.070 に答える