【问题标题】:Control a command line program session via Java通过 Java 控制命令行程序会话
【发布时间】:2014-07-12 14:25:37
【问题描述】:

我有一个计算机代数程序(称为 Reduce),它以交互方式在 shell 中工作:在 shell 中启动 Reduce,然后您可以定义变量、计算这个和那个,以及什么不。 Reduce 将输出打印到 shell 中。我的想法是,我想为这个基于文本的程序构建一个前端,评估其输出并将其转换为一个不错的 LaTeX 样式公式。为此,我想使用 Java。

我可以通过 exec() 启动 Reduce。但是我怎样才能模拟文本输入到打开的 shell,我怎样才能读回 Reduce 写入 shell 的内容?

谢谢 延斯

编辑 1:当前代码

// get the shell
Runtime rt = Runtime.getRuntime();

// execute reduce
String[] commands = {"D:/Programme/Reduce/reduce.com", "", ""};
Process proc = null;
try {
    proc = rt.exec(commands);
} catch (Exception e) {
    System.out.println("Error!\n");
}

// get the associated input / output / error streams
BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
BufferedWriter stdOutput = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));

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

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

【问题讨论】:

    标签: java


    【解决方案1】:

    您需要获取与流程相关的流,包括 InputStream、OutputStream 和 ErrorStream。然后,您可以通过 OutputStream 向进程发送消息,然后通过 InputStream 和 ErrorStream 从进程中读取信息。

    来自我的一些代码:

      final ProcessBuilder pBuilder = new ProcessBuilder(TEST_PROCESS_ARRAY);
    
      final Process proc = pBuilder.start();
    
      procInputStream = proc.getInputStream();
      errorStream = proc.getErrorStream();
    
      errorSBuffer = new StringBuffer();
      streamGobblerSb = new StreamGobblerSb(errorStream, "Autoit Error", errorSBuffer);
      new Thread(streamGobblerSb).start();
    
      final Scanner scan = new Scanner(procInputStream);
    

    【讨论】:

    • 谢谢,但我在 Java 文档中找不到 StreamGobblerSb 类。我在哪里可以找到它?
    • @Jens:哦,抱歉,这些只是我用来处理流的 Runnable 类。您需要创建自己的 Runnable 来处理后台线程中的流。
    • 啊好吧,那只是这里提到的StreamGobbler类? javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html。我想我意识到我需要线程,我上面第 1 版的代码在成功启动应用程序后会挂起。
    • @Jens:您链接的文章是Java后台进程工作的开创性文章之一,建议您好好学习。其中一些有点过时了,例如大多数会使用 ProcessBuilder 而不是 Runtime 来创建流程,但它的突出点仍然至关重要且正确。
    【解决方案2】:

    您可能想研究使用 Process 类。

    http://docs.oracle.com/javase/7/docs/api/java/lang/Process.html

    我相信您可以启动进程,然后使用 getOutputStream() 将命令输入到进程中。

    【讨论】:

    • 谢谢!请参阅我的编辑号。 1 以上为当前状态。问题是while循环在等待更多输出时会自行挂起......我可以把它放在一个线程中吗?
    • 是的,您可以为每个流使用一个线程。这是我见过的一个例子:stackoverflow.com/a/3350862
    【解决方案3】:

    虽然这不是一个严格的答案,但我发现坚持使用 PHP 的函数 proc_open() 更方便。这样我就可以将输出直接包含在前端,而不必担心我的 Java 程序和 html 前端之间的通信。

    对于所有想要坚持 Java 方法的人:文章http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html 是一个很好的参考。

    【讨论】:

      猜你喜欢
      • 2020-03-03
      • 1970-01-01
      • 1970-01-01
      • 2016-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多