簡體   English   中英

如何在 Java 中運行我自己的個性化 bash shell?

[英]How can I run my own personalized bash shell in Java?

我的目標是在 linux 的 bash shell 中執行個性化的提示並執行命令。 結果應該與圖像中的一樣。

在此處輸入圖片說明

所以我想我應該從以下內容開始:

ProcessBuilder builder = new ProcessBuilder();
builder.command("sh");
builder.directory(new File(System.getProperty("user.home")));
Process process = builder.start();

或者

String homeDirectory = System.getProperty("user.home");
Process process;
try {
    System.out.print("# MyShell> ");
    process = Runtime.getRuntime().exec(String.format("sh", homeDirectory));
} catch (IOException e) {
    System.err.println("Error en el método exec()");
    e.printStackTrace();
}

控制異常。

所以基本上是在java中啟動一個個性化的功能性bash提示並控制錯誤消息(比如改變它的顏色)。 還可以使用個性化的詞來控制退出,例如“退出”而不是“退出”。

注意:我不會像這里的許多其他示例一樣嘗試執行腳本或某些命令,例如“tree”或“ls”。 我正在尋找一種方法來運行我的個性化 bash 並執行系統允許我在 bash 中或接近這個想法的所有事情。

由於 shell、終端和您的程序的相互作用,這個問題比看起來更復雜。

鑒於要求是:

  1. 自定義 shell 提示
  2. 自定義命令
  3. 讓shell正常工作
  4. 攔截程序輸出

我的建議是:

  1. 從外殼端進行自定義
  2. 創建一個 pty 以欺騙程序認為他們正在寫入終端。 在 Linux/Mac 上的 Java 中,一種簡單的方法是通過script工具。

這是一個示例 shell 配置文件myrc

export PS1='# MyShell> '
quit() { exit "$@"; }

這是用於啟動自定義 shell 的Shell.java

import java.io.*;
import java.nio.charset.*;
import java.lang.ProcessBuilder.Redirect;

class Shell {
  public static void main(String[] args) throws IOException {
    ProcessBuilder builder = new ProcessBuilder(
        // Use 'script' to fool programs into thinking stdout is a tty.
        "script", "-q", "/dev/null",
        // Run bash with prompt and command customizations
        "bash", "--rcfile", "myrc"
        );
    builder
      // Get input from the current TTY
      .redirectInput(Redirect.INHERIT)
      // But pipe stdout/stderr to intercept it
      .redirectErrorStream(true)
      .redirectOutput(Redirect.PIPE);

    Process proc = builder.start();
    InputStream input = proc.getInputStream();
    byte[] buffer = new byte[65536];
    int read;

    String search = "world";

    while((read = input.read(buffer, 0, buffer.length)) != -1) {
      // Simplify by assuming we only get text data, and only
      // in buffers large enough to contain the entire search string
      String s = new String(buffer, 0, read, StandardCharsets.UTF_8);
      // Replace search word with a highlighted/colored string.
      s = s.replaceAll(search, "\u001B[35m<<$0>>\u001B[m");
      System.out.print(s);
    }

    System.out.println("Java program is exiting...");
  }
}

示例會話顯示自定義提示、工作文本攔截(使“世界”一詞變為紫色並用尖括號括起來),最后是自定義quit命令:

$ javac Shell.java && java Shell
# MyShell> echo "hello world"
hello <<world>>
# MyShell> quit
exit
Java program is exiting...
$

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM