我希望能够从我的Java程序中启动VI并等待用户退出VI,然后再继续。这是我目前的代码片段:
...
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();
}
}
我收到输出:
Vim: output is not to a terminal
Vim: input is not from a terminal
但是后来我看到画面就像VI已经开始一样;和VI不读取我输入的字符。
所以......从/ dev / tty重定向并没有成功。
之前有人必须这样做 - 帮助!
谢谢,
标记
答案 0 :(得分:5)
但是,从Java 1.7开始,您可以使用下一个示例来透明地重定向并具有完整的控制台功能
A = ones(5,5,5);
B = zeros(size(A));
for i = 1 : size(A, 3)
B(:,:,i) = conv2(A(:,:,i), ones(2), 'same');
end
这将允许您透明地为JVM 1.7 +打开VI。
答案 1 :(得分:2)
当Java通过Runtime.exec()
运行程序时(这是commons-exec最终做的),它将程序的输入,输出和错误流作为输入/输出流连接到Java应用程序。这样的流肯定不是终端,你不能移动文本光标(因为它没有任何),更改文本颜色,或检测是否按下Shift
键(因为它只是字节流而不是物理keyborad)。因此,像vi
这样的交互式应用程序无法真正在终端等条件下运行。
顺便说一下,我不确定你提供的命令行args是由shell解析还是直接传递给程序。在后一种情况下,即使有一种方法让Java以某种方式允许程序用其他东西替换Java的连接流,你的/dev/tty
重定向也无法工作。
顺便说一下,为什么你想从Java程序中运行vi
似乎有点奇怪。
所以我想最好的解决方案是执行一个终端模拟器,如konsole
或gnome-terminal
或xterm
,让它通过在命令行上传递相应的参数来运行vi(例如{{ 1}})。在这种情况下,终端的窗口应该弹出,konsole -e vi
可以在其中运行。当然,如果你在无头服务器上它将无法工作,但无论如何运行vi
都无济于事。
答案 2 :(得分:-1)
我不知道如何使用commons-exec,
但标准的Java应该是......
String[] command = {"/usr/bin/vi", "test.txt"};
Process vimProcess = Runtime.getRuntime().exec(command);
vimProcess.waitFor();
这将导致当前线程等待进程完成。你也可以使用 vimProcess.getInputStream(),getOutputStream()和getErrorStream()将这些文件重定向到日志文件或任何你希望它去的地方。
请点击此处了解更多详情。 http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html
希望这有帮助。