我正在编写一个程序,我想在后台启动一个shell,并发送和接收输入和输出。我已经设法做到了这一点,并且可以成功读取和写入此过程。这是我遇到麻烦的地方。
我想在ShellManager
(见下面的代码)中有一个方法,它等待进程完成/失败,并将输入返回给用户。
例如,如果我发送tar xzf something_that_will_take_a_while.tar.gz
,
我可以在输出中看到它如何花费时间,然后回应:
]0;~
[32mMe@MyComputer [33m~[0m
我已经尝试阻止线程,直到收到]0;~
,这不起作用。 (从未返回)
我也试过\u001B
,同样的问题:(
我不确定这个符号是什么,并且在如何检测进程何时返回时找不到多少。
这是我的代码:
package buildSystem.shell;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import base.TermConstants;
public class ShellManager {
private InputStream termOut;
private OutputStream termIn;
private ProcessBuilder build;
private Process main;
BufferedReader reader;
BufferedWriter writer;
public ShellManager() {
build = new ProcessBuilder(TermConstants.getShellLocation());
build.redirectErrorStream(true);
}
public void start() throws IOException {
try {
main = build.start();
termOut = main.getInputStream();
termIn = main.getOutputStream();
reader = new BufferedReader (new InputStreamReader(termOut));
writer = new BufferedWriter(new OutputStreamWriter(termIn));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void writeLine(String s) throws IOException {
writer.write(s);
writer.newLine();
writer.flush();
}
public String readNextLine() throws IOException {
return reader.readLine();
}
public void end() {
try {
writeLine("exit\n");
main.waitFor();
termOut.close();
termIn.close();
reader.close();
writer.close();
} catch (IOException | InterruptedException e) {
kill();
}
}
public void kill() {
main.destroyForcibly();
try {
termOut.close();
termIn.close();
reader.close();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/*THE PART I AM HAVING TROUBLE WITH:*/
public void waitForReturn() {
try {
while(reader.readLine() != "\u001B") {}
} catch (IOException e) {
e.printStackTrace();
}
}
}
基本上,我想要一种可靠的方法来检测程序何时退出bash shell。 bash进程仍将运行,但从该bash实例运行的程序将返回。因此,我无法使用process.waitFor()
。
我尝试等待]0;~
,然后等待[32mMe@MyComputer [33m~[0m
,直到tar退出并出现错误代码,在这种情况下,两行将被反转。我不确定如何继续,因为检测到bash已经返回给用户应该是一个相对容易的任务。
感谢您的帮助!
答案 0 :(得分:1)
如果这代表了您尝试匹配输出的方式,那就是您的问题:
while(reader.readLine() != "\u001B") {}
除特殊情况外,您必须在equals()
个实例上使用String
方法:
while (true) {
String line = reader.readLine();
if ((line == null) || "\u001B".equals(line))
break;
}
我不确定为什么你会在进程退出时期望ESC
和换行符。
答案 1 :(得分:0)
我相信你需要调用Process.waitFor()方法。 所以你需要这样的东西:
Process p = build.start();
p.waitFor()
如果您正在尝试模拟bash shell,则允许输入命令,执行和处理输出而不会终止。有一个开源项目,可能是如何执行此操作的代码的良好参考。它可以在Git上找到。看一下Jediterm Pure Java Emulator。
考虑模拟bash,我也发现Piping between processes的这个例子也很重要。
它确实展示了如何提取正在执行的进程的输出,并将该数据作为输入传递给另一个Java进程。应该会有所帮助。