我正在尝试(并且失败)了解如何从
Java中运行完全交互式的shell程序.
这是场景:
我有一个跨平台的大型GUI应用程序,用Java编写.我试图添加一个交互式命令行环境来运行无头.事情的一面都很好,花花公子.但是,主GUI的一个功能是编辑文件.现在,对于命令行界面,我希望能够执行外部编辑器来编辑文件,然后返回到我保存和退出后的位置.例如,在Linux上它可以执行“vi / path / to / file”.
那么如何以键盘和显示器与应用程序完全交互的方式执行该命令呢?我不希望它在后台运行.我不希望它通过Java重定向IO,我只想让一个命令在“前台”中运行直到它存在.
就好像我在C中使用了system()函数一样.
到目前为止我发现的所有内容都在后台运行命令或通过Java管道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();
}
}
}
我希望Runtime.getRuntime().exec()阻塞直到我完成vi,在此期间所有键盘输入将直接(RAW,因为它已知)直到vi,所有屏幕输出将直接返回,不受影响的,对用户而言.
这就是我在C中实现它的方式:
void main() {
system("vi");
}
更新:
这实现了预期的结果,但是a)仅限于Linux / OSX(不是那么大的问题,但是让它跨平台会很好),并且b)是一个可怕的kludge:
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();
}
}
}