如何使用 Java ProcessBuilder API 运行 交互 bash?
How to run interactive bash using Java ProcessBuilder API?
我正在尝试使用 java ProcessBuilder API:
启动 bash
代码:
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);
}
}
主要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;
}
}
}
我的想法是,我有一个控制台应用程序,我使用 Jline 控制台库创建了它,它有一些我 created/will 创建的自定义命令。
但我希望能够在此控制台中执行 bash(交互模式),以便用户在想要执行某些 bash 命令时不必退出我的控制台应用程序。
使用我拥有的当前代码确实可以启动 bash,并且我也能够执行 bash 命令,但是我没有看到输入到 bash提示。
例如输出:
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
如果你看到上面的 o/p 我看不到我输入的命令(日期,错误命令)但我可以执行它们并获得输出。
我也尝试使用已注释的代码,但它只是挂起并且屏幕上本身没有显示任何提示。
问题:
- 为什么我在 运行 这个终端中看不到我输入的命令?
- 我也尝试使用 RedirectInput、RedirectOutput 作为 PIPE,但是代码挂起,在我 运行 bash 命令
之后我在屏幕上看不到任何东西
- 我应该怎么做才能完成这项工作?
- 当我通过 processBuilder 运行 bash 命令时,我是否也可以加载一个 bashrc 文件作为配置文件,因为它有别名?
我检查了这个:
但我无法理解答案。 bash 仅在从终端调用时才会提示吗?
效果不错
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());
}
使用它我能够看到我输入的内容,但我不知道它为什么有效。如果有人有更好的答案,请post回答。
我正在尝试使用 java ProcessBuilder API:
启动 bash代码:
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);
}
}
主要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;
}
}
}
我的想法是,我有一个控制台应用程序,我使用 Jline 控制台库创建了它,它有一些我 created/will 创建的自定义命令。
但我希望能够在此控制台中执行 bash(交互模式),以便用户在想要执行某些 bash 命令时不必退出我的控制台应用程序。
使用我拥有的当前代码确实可以启动 bash,并且我也能够执行 bash 命令,但是我没有看到输入到 bash提示。
例如输出:
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
如果你看到上面的 o/p 我看不到我输入的命令(日期,错误命令)但我可以执行它们并获得输出。
我也尝试使用已注释的代码,但它只是挂起并且屏幕上本身没有显示任何提示。
问题:
- 为什么我在 运行 这个终端中看不到我输入的命令?
- 我也尝试使用 RedirectInput、RedirectOutput 作为 PIPE,但是代码挂起,在我 运行 bash 命令 之后我在屏幕上看不到任何东西
- 我应该怎么做才能完成这项工作?
- 当我通过 processBuilder 运行 bash 命令时,我是否也可以加载一个 bashrc 文件作为配置文件,因为它有别名?
我检查了这个:
但我无法理解答案。 bash 仅在从终端调用时才会提示吗?
效果不错
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());
}
使用它我能够看到我输入的内容,但我不知道它为什么有效。如果有人有更好的答案,请post回答。