简体   繁体   English

如何使用 Java ProcessBuilder API 运行交互式 bash?

[英]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:问题:

  1. why cant I see the command I typed in the terminal where I run this?为什么我看不到我在运行它的终端中输入的命令?
  2. I tried using RedirectInput, RedirectOutput as PIPE as well, but the code hangs and I am unable to see anything on the screen after I run bash command我也尝试使用 RedirectInput、RedirectOutput 作为 PIPE,但代码挂起,运行 bash 命令后,我无法在屏幕上看到任何内容
  3. What should I do to make this work?我应该怎么做才能完成这项工作?
  4. Could I also load a bashrc file as profile as it has aliases, when I run the bash command through processBuilder?当我通过 processBuilder 运行 bash 命令时,我是否也可以将 bashrc 文件加载为配置文件,因为它具有别名?

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.

相关问题 使用ProcessBuilder使用交互式IO运行C程序 - Run C program with interactive IO using ProcessBuilder 使用 ProcessBuilder 运行 .java 文件 - Run a .java file using ProcessBuilder 通过 bash 和 Java 的 ProcessBuilder api 运行相同的命令得到不同的 output - Same command run via bash and Java's ProcessBuilder api gets different output 如何使用 Java 的 ProcessBuilder.start() 暂停进程运行? - How to pause process run using Java's ProcessBuilder.start()? 如何使用ProcessBuilder从Java运行并行python脚本 - How to run parallel python scripts from java using the ProcessBuilder 如何使用高优先级的ProcessBuilder运行java程序? - How to run a java program using ProcessBuilder in high priority? 如何使用Java ProcessBuilder以访客或受限用户身份运行可执行文件 - How to run a executable as guest or limited user using java ProcessBuilder 如何使用 ProcessBuilder 在 Java 代码中运行 NPM 命令 - How to run NPM Command in Java code using ProcessBuilder 如何在 MacOS 中使用 ProcessBuilder 在 Java 中运行 ffmpeg 命令 - How do you run a ffmpeg command in Java, in MacOS, using a ProcessBuilder 如何使用类ProcessBuilder在Netbeans中运行somethingHere.java? - How to run a somethingHere.java with Netbeans using the Class ProcessBuilder?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM