Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't run bash shell with Java

Why doesn't this code give me the bash prompt? I have tried BufferedReaders and that didn't help.I cannot enter any commands such as 'help' into the console either.

  • Commands such as 'ls' and 'ps' work fine.
  • Running bash with an incorrect argument or '--help' produces output.
  • Running Java as Super User does not help.

Any ideas?

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class Main {
    public static void main(String[] args) {
        try {
            Process p = Runtime.getRuntime().exec("bash");
            InputStream o = p.getInputStream();
            InputStream e = p.getErrorStream();
            OutputStream i = p.getOutputStream();
            while (true) {
                if (o.available() > 0) {
                    System.out.write(o.read());
                }
                if (e.available() > 0) {
                    System.out.write(e.read());
                }
                if(System.in.available() > 0) {
                    i.write((char)System.in.read());
                }
                if(o.available() == 0 && e.available() == 0 && !p.isAlive()) {
                    return;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
like image 566
Chris Smith Avatar asked Nov 20 '25 00:11

Chris Smith


1 Answers

Why doesn't this code give me the bash prompt?

It is not clear what you mean by "the bash prompt" ... but I'm assuming that you are expecting to see the bash prompt characters on the shell's standard output / error streams.

Anyway, the reason is that the shell is not interactive.

The bash manual entry says this:

An interactive shell is one started without non-option arguments and without the -c option whose standard input and error are both connected to terminals (as determined by isatty(3)), or one started with the -i option. PS1 is set and $- includes i if bash is interactive, allowing a shell script or a startup file to test this state.

Note that when you launch a command from Java on Linux / Unix (in the way you are doing) its standard I/O streams will be pipes, and isatty won't recognize them as "terminals".

So, if you want to force the shell to be "interactive", you need to include the "-i" option on the bash command line. For example:

Process p = Runtime.getRuntime().exec(new String[]{"bash", "-i"});
like image 71
Stephen C Avatar answered Nov 22 '25 13:11

Stephen C