Java 如何使Runtime.getRuntime().exec逐个执行命令并获得输出,而不是执行所有命令

Java 如何使Runtime.getRuntime().exec逐个执行命令并获得输出,而不是执行所有命令,java,batch-file,exec,Java,Batch File,Exec,我试图从java应用程序中运行一个*.bat文件(它能够运行多个命令并逐个检索输出)我的目的是发送一个命令,读取输出使用此输出作为第二个命令,然后再次检索输出 为了实现这一点,我通过Runtime.getRuntime().exec将多个命令作为输入传递给PrintWriter。问题是,在完成所有步骤后,我只能通过缓冲区从*.bat读取输出,但我的目的是运行一个命令获取输出,并操纵此输出以发送第二个命令 不幸的是,它不起作用。有什么解决办法吗 我想到了从这个链接()向Runtime.getRun

我试图从java应用程序中运行一个*.bat文件(它能够运行多个命令并逐个检索输出)我的目的是发送一个命令,读取输出使用此输出作为第二个命令,然后再次检索输出

为了实现这一点,我通过Runtime.getRuntime().exec将多个命令作为输入传递给PrintWriter。问题是,在完成所有步骤后,我只能通过缓冲区从*.bat读取输出,但我的目的是运行一个命令获取输出,并操纵此输出以发送第二个命令

不幸的是,它不起作用。有什么解决办法吗

我想到了从这个链接()向Runtime.getRuntime().exec发送多个命令

下面是我从上面链接得到的相同代码

String[] command =
    {
        "cmd",
    };
    Process p = Runtime.getRuntime().exec(command);
    new Thread(new SyncPipe(p.getErrorStream(), System.err)).start();
    new Thread(new SyncPipe(p.getInputStream(), System.out)).start();
    PrintWriter stdin = new PrintWriter(p.getOutputStream());
    stdin.println("dir c:\\ /A /Q");
    // write any other commands you want here
    stdin.close();
    int returnCode = p.waitFor();
    System.out.println("Return code = " + returnCode);
class SyncPipe implements Runnable
{
public SyncPipe(InputStream istrm, OutputStream ostrm) {
      istrm_ = istrm;
      ostrm_ = ostrm;
  }
  public void run() {
      try
      {
          final byte[] buffer = new byte[1024];
          for (int length = 0; (length = istrm_.read(buffer)) != -1; )
          {
              ostrm_.write(buffer, 0, length);
          }
      }
      catch (Exception e)
      {
          e.printStackTrace();
      }
  }
  private final OutputStream ostrm_;
  private final InputStream istrm_;
}

在您的情况下,我不会使用线程,您需要一个顺序执行路径。

实际上,我强烈建议您使用expect-like java库来完成这类工作,而不是尝试重新发明轮子

因为您必须处理一些事情,例如请求之间的超时、等待输出返回等

看看这些库

特别是,我在我的项目中使用了expectj,它工作得非常好(尽管我认为expect4j更受欢迎)

使用expectj,您的代码将如下所示(从)


可以使用管道在bat文件本身中将一个命令的输出重定向到另一个命令。 很抱歉,我没有注意到您希望首先操纵输出。
因此,您可以使用exec从java运行bat文件中的命令,而不是使用bat文件,获取输出,并使用输出执行下一个命令。

首先:不要使用
Runtime.exec()
,使用
ProcessBuilder
。它使重定向更容易处理。@fge我已经尝试过ProcessBuilder,但无法达到我的要求。你能再解释一下吗?谢谢你及时的帮助。在ExpectJ或Expect4J中,我们似乎应该知道要检索回来的确切输出。但在我的问题中,它可以是任意一组整数组合。假设我的输出可以是0102030405或0405060708。从expect或Pattern.compile中,我没有找到任何匹配的逻辑。在expect4j中,您可以期望使用一个正则表达式——请参见本例,以获取输出,并且在Java中不使用相同的过程。这就是我被困的地方。如果我正在终止进程,那么我将无法在同一会话中发送下一个命令。请提供任何帮助主题或有用的链接,以便我可以尝试并让您知道输出。请查看此博客:。请注意,这些线程用于将数据从一个流移动到另一个流,而不是为了启动并行任务。如果它对你有效,也要归功于博主:)
// Create a new ExpectJ object with a timeout of 5s
ExpectJ expectinator = new ExpectJ(5);

// Fork the process
Spawn shell = expectinator.spawn("/bin/sh");

// Talk to it
shell.send("echo Chunder\n");
shell.expect("Chunder");
shell.send("exit\n");
shell.expectClose();