I'm trying to run the command bash -i
from a Java application, because I want the user be able to use the shell in middle of some work and then return to the Java application.
I have this test code:
import java.io.*;
public class exec {
public static void main(String[] args) throws IOException, InterruptedException {
ProcessBuilder b = new ProcessBuilder(args);
b.redirectError(ProcessBuilder.Redirect.INHERIT);
Process p = b.start();
InputStream pout = p.getInputStream();
PrintWriter pin = new PrintWriter(p.getOutputStream());
Thread in = new Thread(() -> {
while (true) {
try {
int i = System.in.read();
if (i == -1) break;
pin.write(i);
pin.flush();
} catch (IOException e) {
e.printStackTrace();
break;
}
}
System.err.println("in finished");
});
Thread out = new Thread(() -> {
while (true) {
try {
int i = pout.read();
if (i == -1) break;
System.out.write(i);
} catch (IOException e) {
e.printStackTrace();
break;
}
}
System.err.println("out finished");
});
out.start();
in.start();
p.waitFor();
}
}
After compiling, everything works well. I can even start the bash
shell:
$ java exec date
ti 21.3.2017 19.03.25 +0200
out finished
^C$ java exec bash
date
ti 21.3.2017 19.03.30 +0200
^Cout finished
However, when I'm trying to start the bash -i
shell, the terminal starts to behave strangely.
$ java exec bash -i
[1] + Stopped (tty input) java exec bash -i
$ user@computer:/tmp$ fg
java exec bash -i
date
date
ti 21.3.2017 19.05.21 +0200
user@computer:/tmp$ pwd
pwd
[1] + Stopped (tty input) java exec bash -i
The Java process is stopped, and the shell is sh
again, I think. After writing fg
the date
command works one time, but the Java is again stopped when I try pwd
.
Is there any way I can get this working? What I want is to have a normal interactive bash prompt started from a Java program.
It appears that the ProcessBuilder
method inheritIO
does what I want.
ProcessBuilder b = new ProcessBuilder(args);
b.inheritIO();
Process p = b.start();