我正在尝试(但失败)弄清楚如何在Java中运行完全交互式的shell程序。
这是场景:
我有一个跨平台并用Java编写的大型GUI应用程序。为此,我试图添加一个交互式的命令行环境以无头运行。这方面的一切都很好,花花公子。但是,主GUI的功能之一是编辑文件。现在,对于命令行界面,我希望能够执行外部编辑器来编辑文件,然后返回保存和退出后的状态。例如,在Linux上,它可以执行“ vi / path / to / file”。
那么,如何以键盘和显示器与应用程序完全交互的方式执行该命令?我不希望它在后台运行。我不希望它通过Java重定向IO,我只希望一个命令“在前台”运行直到存在。
就像我system()在C中使用该函数一样。
到目前为止,我发现的所有内容都在后台运行命令或通过Java通过IO传递IO,这不适用于交互式(非行模式)应用程序。
哦,还有最后一个警告:我仅限于Java 1.6兼容性,所以我不能用做花哨的事情ProcessBuilder。
这是强制性的SSCCE:
class exetest {
public static void main(String[] args) {
try {
Process p = Runtime.getRuntime().exec("vi");
p.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我希望Runtime.getRuntime()。exec()一直阻塞到我完成操作为止vi,在此期间,所有键盘输入都将直接进入(RAW众所周知),vi并且所有屏幕输出都将直接返回,而不会受到影响。用户。
这就是我要在C中实现的方式:
void main() {
system("vi");
}
Run Code Online (Sandbox Code Playgroud)
更新:
这样可以达到预期的结果,但是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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
的精确等效项system("vi")是:
final ProcessBuilder p = new ProcessBuilder("vi");
p.redirectInput(Redirect.INHERIT);
p.redirectOutput(Redirect.INHERIT);
p.redirectError(Redirect.INHERIT);
p.start().waitFor();
Run Code Online (Sandbox Code Playgroud)
(我知道这有3年的延迟,但对于其他有相同问题的人)
小智 -1
首先,ProcessBuilder 也在 Java 6 中。如果您的意思是该版本不充分或其他什么,那么我认为您需要了解两条信息。首先,运行“外部编辑器”的主要方法可能是使用 Runtime 类和 exec 方法。我怀疑这就是你已经在做的事情?其次,您当前的 GUI 在某种程度上有一个“事件循环”,它是一个简单但主要的线程,除了“等待事件”(例如按键或“窗口事件”)之外什么也不做,调度该事件发送给感兴趣的听众,然后等待下一个事件。外部编辑器的按键和事件不会通过此事件循环……好吧,无论如何,如果不使用更复杂的东西(例如 OLE API),这并不容易。但是,正是“事件循环”使 Java 保持活力和交互性,同时其他事情也继续进行,例如在外部编辑器中进行编辑。我不确定您使用的是什么 GUI 框架,但大多数框架已经有这样的循环,您不必担心它。如果您说在您想要的命令行模式下,您不希望正常的 GUI 运行,那么您基本上必须复制具有的“事件循环”,并首先启动该线程,然后调用runtime.exec方法。合理?
FWIW,如果您没有“源代码”来查看当前正在使用的 GUI 框架,如果您想查看一个框架,只是为了了解有关事件循环的更多信息,Eclipse SWT在“显示”类中有一个以及一些示例可能与您想要做的类似。(请注意,SWT 可以“独立”运行,无需 Eclipse 的其余部分,以防您想知道)。
华泰