【问题标题】:In Java, send commands to another command-line program在 Java 中,将命令发送到另一个命令行程序
【发布时间】:2011-02-22 02:03:34
【问题描述】:

我在 Windows XP 上使用 Java,并且希望能够将命令发送到另一个程序,例如 telnet。 我不想简单地执行另一个程序。我想执行它,然后在它运行后向它发送一系列命令。 这是我想要做的代码,但它不起作用: (如果您取消注释并将命令更改为“cmd”,它将按预期工作。请帮助。) 这是一个简化的例子。在生产中会发送更多的命令,所以请不要建议调用“telnet localhost”。

    try
    {
        Runtime rt = Runtime.getRuntime();

        String command = "telnet";
        //command = "cmd";
        Process pr = rt.exec(command);

        BufferedReader processOutput = new BufferedReader(new InputStreamReader(pr.getInputStream()));
        BufferedWriter processInput = new BufferedWriter(new OutputStreamWriter(pr.getOutputStream()));

        String commandToSend = "open localhost\n";
        //commandToSend = "dir\n" + "exit\n";

        processInput.write(commandToSend);
        processInput.flush();

        int lineCounter = 0;
        while(true)
        {
            String line = processOutput.readLine();
            if(line == null) break;
            System.out.println(++lineCounter + ": " + line);
        }

        processInput.close();
        processOutput.close();
        pr.waitFor();
    }
    catch(Exception x)
    {
        x.printStackTrace();
    }

【问题讨论】:

  • 那么你想要一个java的进程间通信解决方案吗?
  • 在我看来,telnet 正在将其输出写入进程输入流以外的其他东西,而 java 没有捕获它。 Process.getInputStream() 是读取进程输出内容的唯一方法吗?

标签: java command-line process send sqlcommand


【解决方案1】:

您可以查看Telnet Ant task,您可以直接在代码中调用它,而无需使用build.xml 文件。

您还可以查看source code,看看他们是如何做到的。

【讨论】:

    【解决方案2】:

    这看起来不错,因为它不会产生那么多输出,但是您应该真正在单独的线程中读取和写入,这样它就不会填满缓冲区并阻塞等待您在进入下一步之前读取。

    因此,如果它达到了刷新发送给它的命令的程度,请通过管道将您发送到其标准输入的文本传送给它,以确定 Windows telnet 客户端是否支持从标准输入而不是控制台接收命令在命令提示符中。

    例如,echo dir c:\ | cmd 使 cmd 运行,列出 c: 驱动器内容并退出,这与您在控制台中键入 dir c:\ 的行为非常相似。但是echo open localhost | telnet 会导致 telnet 清除屏幕然后退出,而不是像您在控制台中键入一样的行为方式。由于 telnet 需要屏蔽用户输入的密码,它很可能使用 console API 而不是从标准输入读取。 help 没有列出任何命令参数来告诉它从标准输入中读取,所以也许你需要使用更适合脚本的 telnet 实现。

    【讨论】:

    • 我同意。这是一个显示我的问题的简化示例,因此我将其保持为单线程。您能否解释一下标准输入与控制台和管道文本的含义?
    • @bradvido 好吧,echo open localhost | telnet 不起作用,但 echo dir c: | cmd 起作用,所以我强烈怀疑 Windows telnet 客户端正在使用控制台 API 来检测按键而不是读取其输入流。跨度>
    • 我现在看到了。这显然是我遇到的问题。您知道如何写入应用程序的控制台而不是输入流吗?
    【解决方案3】:

    如果您想通过 Java 以编程方式控制 telnet 会话,您可以使用 Java telnet library... 您可以执行相同的操作(打开连接、发送用户名/密码、发送命令和接收结果),但是没有实际产生一个单独的进程。

    【讨论】:

    • telent 只是一个例子。我需要它是通用的,以便我可以执行任何可执行文件并向其写入命令
    【解决方案4】:

    这不是直接回答您的问题,而是...

    您应该使用ProcessBuilder 并将stderr 重定向到stdout (ProcessBuilder.redirectErrorStream(true)),而不是使用Runtime.exec()。否则,如果您的进程向stderr 写入内容,您的进程可能会阻塞(当未读取进程的输出时,Windows 不喜欢它)。

    【讨论】:

    • 这非常接近“直接答案” - 您可以启动进程并从Process.getOutputStream() 读取输出并将命令写入Process.getInputStream()
    • 我试过这个,我遇到了同样的问题。不读取来自telent 的输出。程序执行时不打印任何内容。
    • 对 D.Shawley 所写内容的一个小修正,从 Java 代码的角度来看,您实际上 读取 Process.getInputStream()写入 Process.getOutputStream()...命名令人困惑,它们显然是从不同的角度命名的...
    猜你喜欢
    • 2017-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    • 2012-01-26
    • 2023-03-27
    相关资源
    最近更新 更多