Java进程无法通过Runtime.getRunTime().exec()获取InputStream

Java进程无法通过Runtime.getRunTime().exec()获取InputStream,java,linux,shell,runtime,bufferedreader,Java,Linux,Shell,Runtime,Bufferedreader,代码在从进程获取InputStream时出现问题, 因为如果我从终端运行Shell脚本,它会运行得很好, 但是如果我像这样运行脚本,str总是空的 我使用这段代码将Shell脚本的输出直接输入到Java中,而不是将脚本输出写入文件中 是否有其他方法来实现这一点,或者如何使用当前方法解决问题可能的问题是,当您获得输入时,子流程尚未准备就绪 试一试 如果是shell,请编辑您的/home/abhishek/workspace/Pro/run,并在顶部添加以下行 Process process = R

代码在从进程获取InputStream时出现问题, 因为如果我从终端运行Shell脚本,它会运行得很好, 但是如果我像这样运行脚本,str总是空的

我使用这段代码将Shell脚本的输出直接输入到Java中,而不是将脚本输出写入文件中


是否有其他方法来实现这一点,或者如何使用当前方法解决问题

可能的问题是,当您获得输入时,子流程尚未准备就绪

试一试


如果是shell,请编辑您的
/home/abhishek/workspace/Pro/run
,并在顶部添加以下行

Process process = Runtime.getRuntime().exec("bash /home/abhishek/workspace/Pro/run");
InputStream isout = process.getInputStream();    
process.waitFor()
并将所需的执行权限授予
/home/abhishek/workspace/Pro/run

然后使用下面的行

#!/usr/bin/bash

现在,如果运行程序打印任何内容,您应该会在输出中看到它。

您的代码看起来很好。所以,我认为问题要么在您使用的命令行(
bash/home/abhishek/workspace/Pro/run
)中,要么在脚本本身中

我建议您执行以下步骤:

  • 尝试运行一些众所周知的命令,而不是脚本。例如
    pwd
    。检查从输入流读取的代码是否正常工作
  • 现在尝试简化您的脚本。创建只运行相同的
    pwd
    的脚本
    run1
    。现在从java运行这个脚本,看看它是否正常工作。顺便说一句,您不必以
    bash-yourscript
    的方式运行它。您可以不使用
    bash
    前缀直接运行它
  • 如果所有这些都奏效了,就开始一步一步地从简单的脚本过渡到真正的脚本。我相信你会发现你的错误。可能由于某些与环境相关的问题,您的脚本无法启动

  • 试着这样做:

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

    我认为有些东西是通过错误流返回的,因此您可以尝试从进程中检查一些东西。getErrorStream()

    您还应该等待创建的进程阻止主程序在它完成之前完成。使用Process.waitFor()

    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();
    

    问得好,但很难。这与IO阻塞有关,这总是很痛苦的。然而,有一个名为akka()的库,它声称可以克服这样的IO阻塞问题。我已经开始学习它了,我不得不承认它也有它的局限性……您确定脚本是打印到stdout而不是stderr吗?是否从process.getErrorStream()返回了任何内容?
    Runtime.getRuntime()
    返回
    Runtime
    ,而不是process@TechExchange,我建议您在收到否决票之前删除您的答案。在linux中,如果您正在执行程序,“/run”和“run”可能会出现问题。类似这样的行:processprocess=Runtime.getRuntime().exec(“/home/abhishek/workspace/Pro//run”);不起作用?/仅用于引用相对路径。但是,由于我们给出了这样的绝对路径/home/abhishek/workspace/Pro/run,所以它不是必需的。正如我所说的,我运行的是一个Shell脚本,所以它根本不能是./run,如果有任何run.sh会使问题变得更明显的话。嘿,我只是认为我的输出依赖于我正在通过脚本运行的awk程序,它在终端上打印输出,但不会在运行时将其返回到进程,因此是否有方法将awk输出携带到shell中的变量中??我像
    vmstat | awk-f xx.awk那样使用它
    输出由awk文件使用print语句打印,现在我需要将其放入shell脚本中的变量中,您的建议很有用,我需要最后一个帮助。
    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();
    
    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();
       }
    }