0

I am writing a command-line program in Java (https://gitlab.com/gitlabcyclist/secondmemory), and I'd like to be able to run nano so the user can edit questions from within the program. I tried using ProcessBuilder like this:

new ProcessBuilder("nano", "myfile").inheritIO().start();

This doesn't work, though. nano is displayed, but I can't edit the file.

Just to be clear: I want to open nano so that a temporary file can be edited by the user. I'm looking for a way to do something like a system call in C or Ruby.

I'm sorry if there's already an answer to this question. Googling it provides no help, as all of the results are about using nano to edit Java files.

Any help would be appreciated.

Henry Sanger
  • 143
  • 2
  • 15
  • 2
    That ProcessBuilder command works for me. By the way, hard-coding an editor is rude behavior for software. Consider `new ProcessBuilder(System.getenv().getOrDefault("EDITOR", "nano"), file)` instead. The EDITOR environment variable has been used by many many tools to indicate a user’s preferred text editor for literally decades. – VGR Dec 02 '18 at 15:35
  • Are you waiting for the process to complete? You don't show it, or say so. C's `system()` function does wait. If you don't wait, the editor will in fact run, but by the time you manually save an edited file your Java program has used the original one. – dave_thompson_085 Dec 02 '18 at 16:05
  • Yes, I tried `.waitFor()` as well. It didn't really help. I was almost able to use it, but when I tried to use the arrows or press Ctrl-O to save, it just printed the codes (like ^O and ^[OC). – Henry Sanger Dec 02 '18 at 16:41

1 Answers1

0

Because you need to catch the commands and you have to direct to the process. Imagine you started a process on a computer for which you have no keyboard. You need to write the code which sends commands ton the nano shell.

You can take a look at this thread to see how to interact with ProcessBuilder. Here is a the copy-pasted sample code, just follow the link for more details:

public class TestMain {
    public static void main(String a[]) throws InterruptedException {

        List<String> commands = new ArrayList<String>();
        commands.add("telnet");
        commands.add("www.google.com");
        commands.add("80");
        ProcessBuilder pb = new ProcessBuilder(commands);
        pb.redirectErrorStream(true);
        try {

            Process prs = pb.start();
            Thread inThread = new Thread(new In(prs.getInputStream()));
            inThread.start();
            Thread.sleep(2000);
            OutputStream writeTo = prs.getOutputStream();
            writeTo.write("oops\n".getBytes());
            writeTo.flush();
            writeTo.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class In implements Runnable {
    private InputStream is;

    public In(InputStream is) {
        this.is = is;
    }

    @Override
    public void run() {
        byte[] b = new byte[1024];
        int size = 0;
        try {
            while ((size = is.read(b)) != -1) {
                System.err.println(new String(b));
            }
            is.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}
adiian
  • 1,382
  • 2
  • 15
  • 32
  • 1
    I see nothing in the question that suggests sending commands to nano from the Java program. It appears H.A. Sanger just wants to invoke the editor and wait for the user to finish editing a file, the way many command-line version control commands do when committing. – VGR Dec 02 '18 at 15:29
  • Q says 'command line' which normally means a terminal _is_ available, and uses `inheritIO()` which will/would use that terminal. – dave_thompson_085 Dec 02 '18 at 16:06