【问题标题】:Java Interacting with Command Propmt [duplicate]Java与命令提示符交互[重复]
【发布时间】:2018-07-27 17:32:20
【问题描述】:

使用

String cmdString = "cmd.exe /c start python ";
Process p = Runtime.getRuntime().exec(cmdString);

我可以打开命令提示符并运行 python。我现在想与命令提示符交互。我已经阅读了使用

public static void main(String[] args)
{

    BufferedWriter writerToProc;

    String scriptPath = "C:\\Users\\MichaelMi\\Documents\\SourceTree\\NODE-Sensor-Configurator\\src\\application\\resources\\BACnet-CMD-Line-Upgrader\\UpgradeApplication.py";
    String iniPath = "C:\\Users\\MichaelMi\\Documents\\SourceTree\\NODE-Sensor-Configurator\\src\\application\\resources\\BACnet-CMD-Line-Upgrader\\BACpypes.ini";

    String execString  = "python " + scriptPath + " --ini " + iniPath;
    String cmdString = "cmd.exe /c start " + execString ;

    try {
        Process p = Runtime.getRuntime().exec(cmdString);


        writerToProc = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));

        writerToProc.write(cmdString);
        writerToProc.flush();

        writerToProc.write("whois\n");
        writerToProc.flush();

        readErrors(p);
        readOutput(p);

    } catch (IOException e) {
        e.printStackTrace();
    }
}

public static void readOutput(Process p)
{
    BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
    Runnable task = new Runnable() {

        @Override
        public void run() {
            try {
                if(stdInput.ready())
                {
                    stdInput.lines().forEach((l) -> System.out.println(l));
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    };
    Thread backgroundThread = new Thread(task);
    backgroundThread.setDaemon(true);
    backgroundThread.start();
}

public static void readErrors(Process p)
{
    BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
    Runnable task = new Runnable() {

        @Override
        public void run() {
            try {
                if(stdError.ready())
                {
                    stdError.lines().forEach((l) -> System.out.println(l));
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    };
    Thread backgroundThread = new Thread(task);
    backgroundThread.setDaemon(true);
    backgroundThread.start();
}

应该允许我写入打开的命令提示符。但是,这对我不起作用。我没有抛出异常或状态错误。我根本不知道如何写入打开的命令提示符。

【问题讨论】:

  • 你怎么知道你没有收到错误或异常?您是否正在从 Process 的 InputStream 中读取数据?错误流?并在单独的线程中?请向我们展示您的minimal reproducible example 代码,以便我们可以确切地查看您在做什么,更重要的是,您可能做错了什么。另外,不要使用 Runtime,而是使用更新的 ProcessBuilder。 cmd 字符串也应该是字符串的数组或 ArrayList。
  • 我编辑了帖子以显示整个代码。 stdInput 和 stdError 永远不会准备好。我从来没有最终陷入try catch。我打开的命令提示符上没有发布任何内容
  • 您可能永远不会知道,因为所有代码都在同一个线程中运行,并带有阻塞代码。请考虑将您的输入和输出分成不同的线程。
  • 不启动窗口,启动python:试试String cmdString = "python";
  • 我从未见过 .isReady 在任何代码示例中用于从缓冲区读取。但可以工作。你会想做@HovercraftFullOfEels 所说的;然后,您可以编写一个解析器来解析流并将其传递给处理程序,或者只是将代码写入线程。 BufferedReader br = new BufferedReader(fr); String s = null; while ((s=br.readLine())!=null) { System.out.println(s); } 是典型的阅读读者的方法。

标签: java command-prompt


【解决方案1】:

我在您的代码中发现了两个问题:

一个问题是使用的命令行:

cmd.exe /c start python 这将启动一个新的 cmd.exe 实例,该实例本身使用 start 来启动一个分离的 python 进程。因此,分离的进程没有连接到您的 BufferedReader/BufferedWriter。

您的第二个问题是 python 不通过标准输入执行您的“1+1”。 您可以通过使用上下文1+1\n 创建一个文件test 并在控制台上执行它来简单地验证这一点:python < test。您将看不到任何输出。

另见piping from stdin to a python code in a bash script

【讨论】:

  • 这很有意义。所以我已经知道我可以启动一个 python 脚本并向它发送命令。我已经有代码可以做到这一点。有没有办法启动我的 python 脚本并在命令提示符窗口中查看输出?
  • 您想查看输出还是从 Java 中读取?第一个很简单:只需执行cmd.exe /c start python C:/pathxyz/yourpythonfile.py。确保你的 python 文件以time.sleep(5) 结尾,否则当你的脚本完成时窗口会直接关闭。
  • 我的问题是脚本等待 3 个命令。 Whois、readhexfile 和 sendfile。发送文件需要 4 分钟。由于发送被阻止,我发现很难更新我的 java 应用程序 UI。我想解决这个问题并让用户放心的是打开一个命令提示符,向他们显示进度
  • 我在 Java 程序中通过 Jython 执行 python 脚本更好吗?
  • 所以我有可以执行脚本的代码。整个问题是 UI 在那里停留了 4 分钟,最终用户看不到任何更新。
【解决方案2】:

在这种情况下,您需要先关闭输入流,然后才能读取python 进程的输出流。如果有人知道更好的方法,请告诉我们。

public static void main(String[] args) {
    String cmdString = "python";
    try {
        ProcessBuilder pb = new ProcessBuilder(cmdString);
        Process pr = pb.start();
        try (BufferedReader readerOfProc = new BufferedReader(
                new InputStreamReader(pr.getInputStream()));
                BufferedReader errorsOfProc = new BufferedReader(
                        new InputStreamReader(pr.getErrorStream()))) {

            try (BufferedWriter writerToProc = new BufferedWriter(
                    new OutputStreamWriter(pr.getOutputStream()));) {
                writerToProc.write("myVar=1+1\r\n");
                writerToProc.write("print(myVar)\r\n");
                writerToProc.flush();
            } catch (Exception e) {
                e.printStackTrace();
            }

            String s;
            while ((s = readerOfProc.readLine()) != null) {
                System.out.println("stdout: " + s);
            }
            while ((s = errorsOfProc.readLine()) != null) {
                System.out.println("stdout: " + s);
            }

            System.out.println("exit code: " + pr.waitFor());
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

希望这会有所帮助!

【讨论】:

  • 为什么投反对票?该代码有效并回答了 OP 的问题。
猜你喜欢
  • 2013-06-16
  • 1970-01-01
  • 1970-01-01
  • 2011-05-08
  • 2016-03-05
  • 1970-01-01
  • 2014-04-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多