0

My goal is to execute a personalized prompt in a bash shell in linux and to execute orders. The result should be like in the image.

enter image description here

So I suppose I should start with something like:

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

or

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();
}

Controlling the exceptions.

So basically is to start a personalized functional bash prompt in java and control the error messages (like changing its color). Also controlling the exit with a personalized word, like 'quit' instead of 'exit'.

Note: I am not trying to execute a script or some commands like 'tree' or 'ls' like in many other examples around here. I'm looking for a way to run my personalized bash and do everything that the system allows me in bash or close to this idea.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Lothar
  • 39
  • 5
  • What happened when you tried your own suggestions? – user14387228 Oct 17 '20 at 15:59
  • Why would you want to do that? Java is intended to run on **all** OS, so they don't have bash, mostly, and will crash or else have a decent error message. Why using java to access bash? – Gyro Gearloose Oct 17 '20 at 16:00
  • What happened when you tried your own suggestions? I couldn't make it work. – Lothar Oct 17 '20 at 16:10
  • I don't want to run the program in windows or mac, just try this in linux. – Lothar Oct 17 '20 at 16:11
  • So you have some sample code there. What happened when you tried to implement it? What's the actual problem you're facing? Stack Overflow is meant to address specific technical issues, but you're asking people to make a design decision for you. Take a look at the Stack Overflow help file sections on [how to ask](https://stackoverflow.com/help/how-to-ask) and [on topic](https://stackoverflow.com/help/on-topic), which will help you formulate questions that are in scope for this site. – MarsAtomic Oct 17 '20 at 16:53
  • What happened when you tried to implement it? that it doesn't work as I expected, it doesn't do what I am trying to do and I don't see where is the problem after looking in Stckoverglow, github, google.... – Lothar Oct 17 '20 at 17:02
  • Does this answer your question? [Run shell script from java code](https://stackoverflow.com/questions/49558546/run-shell-script-from-java-code) – blckCoach Oct 17 '20 at 17:12
  • Thanks @blckCoach, That mostly does exactly the same I accomplished.... but it does not answer my question.... What 'that answer' does is to run a shell that looks works in the background because I can't know if it is getting my commands since it doesn't show any result either... – Lothar Oct 17 '20 at 17:29
  • Instead of saying "it doesn't work", please be specific. For example "the Java program appears to hang. When I type `ls` and press enter, I expected it to show files in the directory. Instead, nothing happens. The program does not respond at all until I press ctrl-c to kill it" – that other guy Oct 17 '20 at 17:30
  • 1
    You have said why this other question isn't what you want. When people asked what's wrong with the code *you* posted, you only said "I couldn't make it work", "it doesn't work as I expected", "it doesn't do what I am trying to do". I am sure it's obvious to you, but other people can't see your screen. Imagine going to the doctor and saying "it doesn't work" instead of "I can't see from my left eye" – that other guy Oct 17 '20 at 17:38

1 Answers1

1

This problem is more complex than it appears due to the interplay of the shell, the terminal, and your program.

Given that the requirements are:

  1. Custom shell prompt
  2. Custom commands
  3. Have the shell work normally
  4. Intercept the program output

My suggestion is:

  1. Do the customizations from the shell side
  2. Create a pty to fool programs into thinking they're writing to a terminal. In Java on Linux/Mac, a simple way to do this is via the script tool.

Here's an example shell configuration file myrc:

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

and here's Shell.java to start the custom shell:

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...");
  }
}

Example session showing custom prompt, working text interception (making the word "world" purple and surrounded by angle brackets), and finally the custom quit command:

$ javac Shell.java && java Shell
# MyShell> echo "hello world"
hello <<world>>
# MyShell> quit
exit
Java program is exiting...
$
that other guy
  • 116,971
  • 11
  • 170
  • 194
  • First of all thanks for your help. Unfortunately I can't check the code since I get this error: script: unrecognized option '--rcfile' I've checking in google the bash options and it should be fine but I don't know why the program keeps giving me that error. – Lothar Oct 17 '20 at 19:35
  • I tested this on macOS `script`. From reading the Linux man page, it sounds like it should be `"script", "-c", "bash --rcfile myrc", "/dev/null"` though I'm not able to test it – that other guy Oct 17 '20 at 19:49
  • Yes, that's perfect. Thank you very much. Now I'm going to study the code to understand how it works. I don't like just copy/paste ;) – Lothar Oct 17 '20 at 19:55