Java 与命令提示符交互

Java Interacting with Command Propmt

使用

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

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

我发现你的代码有两个问题:

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

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 进程的输出流。如果有人知道更好的方法,请告诉我们。

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

希望对您有所帮助!