[英]Send multiples commands with ProcessBuilder?
I want to spawn a child process in Java and send different commands inside the app.我想在 Java 中生成一个子进程并在应用程序内发送不同的命令。 My child process has authentication and each user can have a variety of internal commands.
我的子进程具有身份验证,每个用户都可以拥有各种内部命令。
For example:例如:
> login myuser passowrd
OK
> list certs
cert1 abc
cert2 efg
> logout
> exit
Well, to simulate that I will make my example with "node" as IO CLI.好吧,为了模拟,我将使用“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;
}
}
I expect to print 1,2,3,4
and get the res any text...
for this example.我希望打印
1,2,3,4
并获取 res any text...
对于这个例子。 But the program never stops and stay in 1,2
.但是程序永远不会停止并停留在
1,2
中。 If I close the writer
after the flush in 1
I get this output:如果我在
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)
That's why I close the writer
and the reader
works but I can't write again.这就是为什么我关闭
writer
和reader
工作,但我不能再写。 So, how I can make to send multiples commands to the child app and read the output to follow the flow with other commands?那么,我如何才能向子应用程序发送多个命令并阅读 output 以跟随其他命令的流程?
One problem is that your while loops一个问题是你的 while 循环
while ((buff = reader.readLine()) != null) { ... }
only terminate when the reader
has reached the end of the input stream.仅当
reader
到达输入 stream 的末尾时才终止。
The end of the input stream is only reached when the subprocess terminates.输入 stream 仅在子进程终止时到达末尾。
The second problem is that you seem to be using NodeJS as sample command executor.第二个问题是您似乎使用 NodeJS 作为示例命令执行器。
-i
parameter (force interactive mode), at the expense of some additional output.-i
参数(强制交互模式)启动 NodeJS,但会牺牲一些额外的 output。 To achieve this, you would create the ProcessBuilder
with为此,您将创建
ProcessBuilder
ProcessBuilder pb = new ProcessBuilder("node", "-i");
Communicating with a subprocess in this way only works when you know how many lines to read from the reader
before sending the next command.仅当您知道在发送下一个命令之前要从
reader
读取多少行时,以这种方式与子进程通信才有效。
Knowing how many lines to read can mean:知道要阅读多少行可能意味着:
The list certs
command could either: list certs
命令可以:
produce生产
cert1 abc cert2 def END
produce (where the last line would be empty instead of containing a dot)产生(最后一行是空的而不是包含一个点)
cert1 abc cert2 def.
produce生产
2 certs cert1 abc cert2 def
or you could execute a count certs
command before executing list certs
或者您可以在执行
list certs
之前执行count certs
命令
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.