在 Java 中,将命令发送到另一个命令行程序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2877609/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 23:14:58  来源:igfitidea点击:

In Java, send commands to another command-line program

javacommand-lineprocesssendsqlcommand

提问by bradvido

I am using Java on Windows XP and want to be able to send commands to another program such as telnet. I do not want to simply execute another program. I want to execute it, and then send it a sequence of commands once it's running. Here's my code of what I want to do, but it does not work: (If you uncomment and change the command to "cmd" it works as expected. Please help.) This is a simplified example. In production there will be many more commands sent, so please don't suggest calling "telnet localhost".

我在 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();
    }

采纳答案by Pete Kirkham

That looks OK, as it won't be producing that much output, but you should really read and write in separate threads so it doesn't fill up the buffer and block waiting you to read before you reach the next step.

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

So if it's reaching the point where you flush the command you send to it, find out whether the Windows telnet client supports receiving commands from standard input rather than a console by piping the text you're sending to its standard input to it in a command prompt.

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

For example, echo dir c:\ | cmdcauses cmd to run, list the c: drive contents and exit, much the same behaviour as if you typed dir c:\into the console. But echo open localhost | telnetcauses telnet to clear the screen then exit, rather than behaving the same way as if you typed it into the console. As telnet needs to mask user input for passwords, it's quite likely that it's using the console APIrather than reading from standard input. It's helpdoesn't list any command arguments to tell it to read from standard input, so maybe you need to use a telnet implementation which is better suited to scripting.

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

回答by tangens

It's not directly an answer to your question, but...

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

Instead of using Runtime.exec()you should use a ProcessBuilderand redirect stderrto stdout(ProcessBuilder.redirectErrorStream(true)). Otherwise your process could block if it writes something to stderr(Windows doesn't like it when the output of a process isn't read).

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

回答by psmears

If you want to control a telnet session programatically from Java, you might be able to use this Java telnet library... you can do the same things (open connections, send username/password, send commands and receive results) but without actually spawning a separate process.

如果您想从 Java 以编程方式控制 telnet 会话,您可以使用此Java telnet 库……您可以执行相同的操作(打开连接、发送用户名/密码、发送命令和接收结果),但无需实际生成一个单独的过程。

回答by OscarRyz

You may take a look at the Telnet Ant taskyou can call it directly in your code with out having to use a build.xmlfile.

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

You can also take a look at the source codeand see how they do it.

您还可以查看源代码,看看他们是如何做到的。