使用apache commons exec运行交互式命令

时间:2010-08-17 17:01:34

标签: java windows-7 apache-commons

我想用apache commons exec运行一个交互式命令。一切正常,但是当我执行命令并等待用户输入时,我没有在控制台中看到我的输入,直到我按下Enter键使其无法使用。

这是交互式程序的一个示例:

public static void main(String[] args) {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String line = null;
        while (true) {
            System.out.print("=> ");
            try {
                line = in.readLine();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(line);
        }
    }

现在我想用apache commons exec执行它,如下所示:

public static void main(String[] args) {
    Executor ex = new DefaultExecutor();
    ex.setStreamHandler(new PumpStreamHandler(System.out, System.err, System.in));
    CommandLine cl = new CommandLine("java");
    cl.addArguments("-cp target\\classes foo.bar.Main");

    try {
        ex.execute(cl);
    } catch (ExecuteException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

正如我所说,它基本上有效,我得到了“=>”提示,但是当我输入内容时,我才看到它,直到我按下回车键。我在带有cmd提示符的Windows 7上执行此操作。 我很欣赏任何关于如何实现理想行为的暗示。

编辑:在Linux上按预期工作。我想这是windows cmd提示符的问题。如果可能的话,我仍然希望能够完成这项工作,所以我很感激能够对Windows上的这种行为有所了解。

Edit2:我还使用msys shell和powershell进行了测试,两者都表现出同样的问题。

Edit3:我通过启动单独的cmd提示解决了这个问题。这有效,但我仍然想明白为什么。

CommandLine cl = new CommandLine("cmd");
cl.addArguments("/C java -cp target\\classes foo.bar.Main");

感谢

拉​​乌尔

2 个答案:

答案 0 :(得分:2)

我不确定你到底想要发生什么;如果生成的进程被设计为等待从其输入中读取,那么当它确实发生时它应该不会令人惊讶吗?

如果这是问题所在,您的问题是“如何让我的程序自动向生成的进程发送换行符?”,那么您需要定义OutputStream来编写输入来,并抓住ExecuteStreamHandler将其附加到流程。如下所示:

Executor ex = new DefaultExecutor();

// Create an output stream and set it as the process' input
OutputStream out = new ByteArrayOutputStream();
ex.getStreamHandler().setProcessInputStream(out);
...
try
{
    ex.execute(cl);
    out.write("\n".getBytes()); // TODO use appropriate charset explicitly
...

答案 1 :(得分:0)

使用Apache exec org.apache.commons.exec.DefaultExecuteResultHandler可以启动非阻塞命令。然后你可以按照@Andrzej提到的步骤进行操作。