Running an interactive shell in Java

I am trying (and failing) to decide how I can run a fully interactive shell program from Java.

Here's the script:

I have a great GUI application that is cross-platform and written in Java. In that I am trying to add an interactive command line environment to run headless. This side of things is beautiful and dandy. However, one of the functions of the main GUI is file editing. Now for the command line interface, I want to be able to run an external editor to edit files, and then go back to where I was after I saved and exited. For example, on Linux, it can execute "vi / path / to / file".

So, how can I execute this command in such a way that the keyboard and display are fully interactive for the application? I do not want it to work in the background. I don’t want it to redirect IO through Java, I just want one single command to run “in the foreground” as long as it does not exist.

Just as if I were using a function system()in C.

Everything that I have found so far executes commands in the background or passes IO through Java, which will not work for interactive (non-linear) applications.

Oh, and one final caveat: I'm limited to compatibility with Java 1.6, so I can't do fancy things with ProcessBuilder.

Here's the required SSCCE:

class exetest {
    public static void main(String[] args) { 
        try {
            Process p = Runtime.getRuntime().exec("vi");
            p.waitFor();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

, Runtime.getRuntime(). exec() , vi, (RAW, ) vi , , .

C:

void main() {
    system("vi");
}

Update:

, a) Linux/OSX ( , -), b) :

import java.io.*;

class exetest {
    public static void main(String[] args) {
        try {
            Process p = Runtime.getRuntime().exec("/bin/bash");
            OutputStream stdin = p.getOutputStream();
            PrintWriter pw = new PrintWriter(stdin);
            pw.println("vi < /dev/tty > /dev/tty");
            pw.close();
            p.waitFor();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
+4
3

, kludge, , , , - .

, Windows.

bash:

class Exetest {
    public static void main(String[] args) { 
        try {
            // Create a one-liner for bash
            // Note that the trick is to do all the redirects and
            // give the name of the file in a single argument.
            String [] commandline = new String[3];
            commandline[0] = "bash";
            commandline[1] = "-c";
            commandline[2] = "vi </dev/tty >/dev/tty test.txt";
            Process p = Runtime.getRuntime().exec(commandline);
            p.waitFor();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

.

+3

system("vi"):

final ProcessBuilder p = new ProcessBuilder("vi");
p.redirectInput(Redirect.INHERIT);
p.redirectOutput(Redirect.INHERIT);
p.redirectError(Redirect.INHERIT);

p.start().waitFor();

( , 3- , )

0

, -, ProcessBuilder Java 6. - , , . -, "exernal editor", , Runtime exec. , ? -, - " " , , , , " " (, " " ), , . ... , , , - , OLE API. " " Java , , , . , , , . , , , , " " , , , runtime.exec . ?

FWIW, if you don’t have the source of the “source” that you are currently using in the GUI, if you want to see it just to learn more about event loops, Eclipse SWT has one in its class “Show” and some examples that may look like what you want to do. (Note: SWT can work autonomously without the rest of Eclipse if you're interested.)

NTN

-1
source

All Articles