簡體   English   中英

使用 ProcessBuilder 發送多個命令?

[英]Send multiples commands with ProcessBuilder?

我想在 Java 中生成一個子進程並在應用程序內發送不同的命令。 我的子進程具有身份驗證,每個用戶都可以擁有各種內部命令。

例如:

> login myuser passowrd
OK
> list certs
cert1 abc
cert2 efg
> logout
> exit

好吧,為了模擬,我將使用“node”作為 IO CLI 來制作我的示例。

public class JAVAMain {

    public static void main(String[] args) throws Exception {
        action();
    }

    public static String action() throws Exception {
        ProcessBuilder pb = new ProcessBuilder("node");
        pb.redirectErrorStream(true);
        Process process = pb.start();

        // streams
        InputStream stdout = process.getInputStream();
        OutputStream stdin = process.getOutputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(stdout));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin));
        String buff = "";
        String res = "";

        System.out.println("1");
        writer.write("console.log('OK');\n"); // simulate "login answer"
        writer.flush();

        System.out.println("2");
        res = "";
        while ((buff = reader.readLine()) != null) {
            res += buff;
        }

        if (!res.equals("OK")) {
            reader.close();
            writer.close();
            throw new Exception("Invalid auth");
        }

        System.out.println("3");
        writer.write("console.log('any text...');\n");
        writer.flush();

        System.out.println("4");
        res = "";
        while ((buff = reader.readLine()) != null) {
            res += buff;
        }

        reader.close();
        writer.close();
        return res;
    }
}

我希望打印1,2,3,4並獲取 res any text...對於這個例子。 但是程序永遠不會停止並停留在1,2中。 如果我在1刷新后關閉編寫writer ,我會得到這個 output:

1
2
3
Exception in thread "main" java.io.IOException: Stream closed
        at java.io.BufferedWriter.ensureOpen(BufferedWriter.java:116)
        at java.io.BufferedWriter.write(BufferedWriter.java:221)
        at java.io.Writer.write(Writer.java:157)
        at com.keynua.kades.JAVAMain2.action(JAVAMain2.java:48)
        at com.keynua.kades.JAVAMain2.main(JAVAMain2.java:14)

這就是為什么我關閉writerreader工作,但我不能再寫。 那么,我如何才能向子應用程序發送多個命令並閱讀 output 以跟隨其他命令的流程?

一個問題是你的 while 循環

while ((buff = reader.readLine()) != null) { ... }

僅當reader到達輸入 stream 的末尾時才終止。

輸入 stream 僅在子進程終止時到達末尾。


第二個問題是您似乎使用 NodeJS 作為示例命令執行器。

  • 如果 NodeJS 是從控制台啟動的,可以輸入 JavaScript 語句,然后一一執行。
  • 但是,您不是從控制台啟動 NodeJS,而是從其他一些應用程序啟動。 在這種情況下,NodeJS 想要從標准輸入讀取完整的腳本並立即執行完整的腳本
  • 您可以使用-i參數(強制交互模式)啟動 NodeJS,但會犧牲一些額外的 output。

為此,您將創建ProcessBuilder

ProcessBuilder pb = new ProcessBuilder("node", "-i");

僅當您知道在發送下一個命令之前要從reader讀取多少行時,以這種方式與子進程通信才有效。

知道要閱讀多少行可能意味着:

  • 知道命令產生多少行 output (登錄:1 行 output,注銷:無輸出)
  • 知道命令會產生不同的最后一行(例如空行或僅包含“END”的行)
  • 一個命令產生一個行數作為第一個結果
  • 首先執行另一個命令,返回后續命令的結果行數

list certs命令可以:

  • 生產

     cert1 abc cert2 def END
  • 產生(最后一行是空的而不是包含一個點)

     cert1 abc cert2 def.
  • 生產

     2 certs cert1 abc cert2 def
  • 或者您可以在執行list certs之前執行count certs命令

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM