简体   繁体   English

发送命令到正在运行的Python脚本

[英]Send commands to Running Python Script

I am working on a small java app that needs to start a python script and interact with it. 我正在开发一个小型Java应用程序,该应用程序需要启动python脚本并与其进行交互。 The python script is to run in the background and wait for commands. python脚本将在后台运行并等待命令。 After each command I expect a response which will be forwarded back to the java app. 在执行每个命令之后,我希望得到一个响应,该响应将转发回Java应用程序。

I have used the examples here and here to open the python script. 我在这里这里都使用了示例来打开python脚本。

My question is how do I, without re-running the python script hook into it and run my commands? 我的问题是如何在不重新运行python脚本钩子的情况下运行命令?

public void startProcess()
{
    try {
        p = Runtime.getRuntime().exec("python " + scriptPath);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public String executeCommand(String cmd)
{
    String consoleResponse = "";

    try {
        // how do I perform something similar to p.exec(cmd)

        BufferedReader stdInput = new BufferedReader(new
                 InputStreamReader(p.getInputStream()));

        BufferedReader stdError = new BufferedReader(new
                 InputStreamReader(p.getErrorStream()));

        // read the output from the command
        System.out.println("Here is the standard output of the command:\n");
        while ((consoleResponse += stdInput.readLine()) != null) {
        }

        // read any errors from the attempted command
        System.out.println("Here is the standard error of the command (if any):\n");
        while ((consoleResponse = stdError.readLine()) != null) {
        }

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

    return consoleResponse;
}

EDIT: The python script is for BACpypes. 编辑:python脚本用于BACpypes。 The script does 3 things. 该脚本执行3件事。 WhoIs: gets a list of all devices connected over bacnet ReadHexFile: reads in a text file to be sent to all devices on the network SendFile: sends the file to all devices. WhoIs:获取通过bacnet连接的所有设备的列表ReadHexFile:读取要发送到网络上所有设备的文本文件。SendFile:将文件发送到所有设备。

I am not experienced with python and feel it would be simpler to keep all this data in one script. 我对python没有经验,因此将所有这些数据保存在一个脚本中会更简单。

I suppose one option is to break each command into its own script and pass the data to the java application. 我想一个选择是将每个命令分解成自己的脚本,然后将数据传递给Java应用程序。

how do I, without re-running the python script hook into it and run my commands? 如何在不重新运行python脚本钩的情况下运行它并运行命令?

You would need to make the single Python script keep listening for the new input or requests (back and forth communication), but I think that would be a slight pain and also makes your python script less clear than the standard input -> process -> output flow. 您将需要使单个Python脚本继续监听新的输入或请求(来回通信),但是我认为这会有些痛苦,并且会使您的python脚本不如标准input -> process -> output清晰。 input -> process -> output流量。

What is the reason for avoiding running multiple Python scripts? 避免运行多个Python脚本的原因是什么?


To write input to your scripts stdin, do something like this: 要将输入写入脚本标准输入,请执行以下操作:

public static void main(String[] args) throws IOException, InterruptedException {
    ProcessBuilder pb = new ProcessBuilder("python", "path\\to\\script.py");
    Process pr = pb.start();

    try (BufferedWriter writerToProc = new BufferedWriter(
            new OutputStreamWriter(pr.getOutputStream()));
            BufferedReader readerOfProc = new BufferedReader(
                    new InputStreamReader(pr.getInputStream()));
            BufferedReader errorsOfProc = new BufferedReader(
                    new InputStreamReader(pr.getErrorStream()))) {

        writerToProc.write("WhoIs\n");
        writerToProc.write("ReadHexFile\n"); // is this the syntax?
        writerToProc.write("SendFile 'path\to\file.txt'\n");
        writerToProc.flush();

        StringBuilder procOutput = new StringBuilder();
        boolean gaveUp = false;
        long waitTime = 10 * 1_000; // 10 seconds
        long lastRead = System.currentTimeMillis();
        for(;;) {
             final long currTime = System.currentTimeMillis();
             final int available = readerOfProc.available();
             if(available > 0){
                 // TODO read the available bytes without blocking
                 byte[] bytes = new byte[available];
                 readerOfProc.read(bytes);
                 procOutput.append(new String(bytes));

                 // maybe check this input for an EOF code
                 // your python task should write EOF when it has finished
                 lastRead = currTime;
             } else if((currTime - lastRead) > waitTime){
                 gaveUp = true;
                 break;
             }
        }


        // readerOfProc.lines().forEach((l) -> System.out.println(l));
        // errorsOfProc.lines().forEach((l) -> System.out.println(l));
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM