[英]How to run interactive bash using Java ProcessBuilder API?
I am trying to start bash using java ProcessBuilder API:我正在尝试使用 java ProcessBuilder API 启动 bash:
code:代码:
public class BashExecutor {
public void executeCommand(String[] command, Consumer<String> consumer) {
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command(command);
processBuilder.redirectErrorStream(true);
processBuilder.inheritIO();
//processBuilder.redirectInput(ProcessBuilder.Redirect.PIPE);
//processBuilder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
try {
Process process = processBuilder.start();
/*ProcessStreamConsumer streamConsumer = new ProcessStreamConsumer(process.getInputStream(), consumer);
streamConsumer.consumeStream();*/
process.waitFor();
if(process.isAlive()){
process.destroyForcibly();
}
} catch (Exception e) {
consumer.accept(e.getMessage());
}
}
ProcessStreamConsumer:流程流消费者:
public class ProcessStreamConsumer {
private InputStream inputStream;
private Consumer<String> consumer;
public ProcessStreamConsumer(InputStream inputStream, Consumer<String> consumer) {
this.inputStream = inputStream;
this.consumer = consumer;
}
public void consumeStream() {
new BufferedReader(new InputStreamReader(inputStream)).lines()
.forEach(consumer);
}
}
Main class:主class:
class Console{
public final ConsoleReader console;
public final BashExecutor bashExecutor;
public Console() throws IOException {
console = new ConsoleReader();
console.setExpandEvents(false);
bashExecutor = new BashExecutor();
}
public void println(Object in){
try {
console.println(in.toString());
console.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Console consoleMain = new Console();
String input = consoleMain.console.readLine("grid>");
while(true){
if(input==null) input= "stop";
input = input.trim();
while(input.trim().equals("")){
input = console.readLine(grid>);
}
if(input.startsWith("stop") || input.startsWith("qui")){
System.exit(0);
}
if(input.startsWith("bash")) {
bashExecutor.executeCommand(input, this::println);
input=console.readLine("grid>");
continue;
}
}
}
The idea is that I have console app which I have created using the Jline console library which has some custom commands which I have created/will create.这个想法是我有我使用 Jline 控制台库创建的控制台应用程序,其中包含一些我已经创建/将创建的自定义命令。
But I want to be able to execute bash (interactive mode) in this console so that users dont have to quit my console app if they want to execute some bash commands.但我希望能够在此控制台中执行 bash(交互模式),以便用户在执行某些 bash 命令时不必退出我的控制台应用程序。
with current code that I have it does start the bash and I am able to execute the bash commands as well, But I dont see the input that I am typing to the bash prompt.使用我拥有的当前代码,它确实启动了 bash 并且我也能够执行 bash 命令,但是我没有看到我在 ZD574D4BB40C84861791A694A999CCE 提示符下输入的输入。
eg output:例如 output:
grid>bash
bash-4.2$ Mon Jun 15 02:57:14 EDT 2020
bash-4.2$ bash: wrongcommand: command not found
bash-4.2$ exit
grid>quit
If you see the above o/p I cannot see the commands that I had typed(date, wrongcommand) but I could execute them and get the output.如果您看到上面的 o/p,我看不到我输入的命令(日期,错误命令),但我可以执行它们并获取 output。
I tried using the code that is commented as well, but that just hangs and no prompt is displayed on the screen itself.我也尝试使用已注释的代码,但这只是挂起并且屏幕本身没有显示任何提示。
Questions:问题:
I checked this: Invoking bash from Java interactively我检查了这个: Invoking bash from Java interactive
but I could not understand the answer.但我无法理解答案。 will bash prompt only when it is invoked from the terminal?
只有从终端调用 bash 才会提示?
This worked well这运作良好
ProcessBuilder processBuilder = new ProcessBuilder();
try {
processBuilder.command("stty", "echo");
processBuilder.inheritIO();
processBuilder.start().waitFor(1000, TimeUnit.MILLISECONDS);
processBuilder.command("bash", "-i");
processBuilder.redirectErrorStream(true);
processBuilder.inheritIO();
processBuilder.start().waitFor();
processBuilder.command("stty", "-echo");
processBuilder.inheritIO();
processBuilder.start().waitFor(1000, TimeUnit.MILLISECONDS);
} catch (Exception e) {
consumer.accept("exception occurred while starting bash");
consumer.accept(e.getMessage());
}
using which I was able to see what I was typing, but I don't know why it works.使用它我可以看到我正在输入的内容,但我不知道它为什么会起作用。 if anyone has a better answer please do post it.
如果有人有更好的答案,请发布。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.