Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.8k views
in Technique[技术] by (71.8m points)

shell - How can I launch VI from within Java under commons-exec?

I would like to be able to launch VI from within my Java program and wait for the user to quit VI before proceeding. Here's the code snippet that I have currently:

...    
String previewFileName="test.txt"; // the file to edit
CommandLine cmdLine = new CommandLine("/usr/bin/vi");
cmdLine.addArgument(previewFileName);
cmdLine.addArgument(">/dev/tty");
cmdLine.addArgument("</dev/tty");

Executor executor = new DefaultExecutor();
try
{
    DefaultExecuteResultHandler resultHandler = new ResetProcessResultHandler(cmdLine);
    executor.execute(cmdLine, resultHandler);
} catch (IOException e)
{
    throw new Error("Cannot execute command: /usr/bin/vi " + previewFileName, e);
}
log.info("waiting...");
cmdLine.wait();
log.info("...done");
...

private class ResetProcessResultHandler extends DefaultExecuteResultHandler
{
    private final CommandLine mCommandLine;
    public ResetProcessResultHandler(CommandLine pCommandLine)
    {
        mCommandLine = pCommandLine;
    }
    public void onProcessComplete(int exitValue)
    {
        log.info("Command complete  rc(" + exitValue + ")");
        if (exitValue != 0)
        {
            throw new RuntimeException("VI command error [rc=" + exitValue + "] " );
        }
        mCommandLine.notify();
    }
    public void onProcessFailed(ExecuteException e)
    {
        if (e.getExitValue() != 0)
        {
            log.error("launch VI error " + e.toString());
            throw new RuntimeException("VI command failed [" + e.getCause() + "] ");
        }
        else
        {
            log.info("VI complete   rc(" + e.getExitValue() + ")");
        }
        mCommandLine.notify();
    }
}

I receive output:

Vim:  output is not to a terminal
Vim:  input is not from a terminal

But then I see the screen painted as if VI had started; and VI doesn't read characters I type.

So ... redirecting from /dev/tty isn't doing the trick.

Someone must have done this before - help!

Thanks,

Mark

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

However since Java 1.7 you can use the next example to transparently redirect and have full console functionality

System.out.println("STARTING VI");
 ProcessBuilder processBuilder = new ProcessBuilder("/usr/bin/vi");
 processBuilder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
 processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
 processBuilder.redirectInput(ProcessBuilder.Redirect.INHERIT);

 Process p = processBuilder.start();
  // wait for termination.
  p.waitFor();
System.out.println("Exiting VI");

This will allow you to open VI transparently for JVM 1.7+.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...