本文介绍了在Java中运行交互式Shell程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试(但失败)弄清楚如何在Java中运行完全交互式的shell程序.

I am trying (and failing) to work out how I can run a fully interactive shell program from within Java.

这是场景:

我有一个跨平台并用Java编写的大型GUI应用程序.为此,我试图添加一个交互式的命令行环境来运行无头程序.这方面的一切都很好,花花公子.但是,主GUI的功能之一是编辑文件.现在,对于命令行界面,我希望能够执行外部编辑器来编辑文件,然后返回保存和退出后的状态.例如,在Linux上,它可以执行"vi/path/to/file".

I have a large GUI application which is cross platform and written in Java. Into that I am trying to add an interactive command line environment for running headless. That side of things is all fine and dandy. However, one of the functions of the main GUI is editing of files. Now, for the command line interface I want to be able to execute an external editor to edit the files, then return back to where I was after I have saved and exited. For example, on Linux it may execute "vi /path/to/file".

那么,如何以键盘和显示器与应用程序完全交互的方式执行该命令?我不希望它在后台运行.我不希望它通过Java重定向IO,我只希望一个命令在前台"运行,直到它存在为止.

So how can I execute that command in such a way that the keyboard and display are fully interactive to the application? I don't want it to run in the background. I don't want it to redirect IO through Java, I just want that one single command to run "in the foreground" until it exists.

就像我在C语言中使用system()函数一样.

Just like as if I'd used the system() function in C.

到目前为止,我发现的所有内容都在后台运行命令或通过Java通过管道传输IO,这不适用于交互式(非行模式)应用程序.

Everything I have found so far runs commands in the background or pipe the IO through Java, which won't work for interactive (non line-mode) applications.

哦,还有最后一个警告:我仅限于Java 1.6兼容性,所以我不能用ProcessBuilder做花哨的事情.

Oh, and one final caveat: I'm restricted to Java 1.6 compatibility, so I can't do fancy things with ProcessBuilder.

这是强制性的SSCCE:

Here's the obligatory 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并且所有屏幕输出都将直接返回给用户,而不会受到任何影响.

I would expect the Runtime.getRuntime().exec() to block until I had finished in vi, and during that time all keyboard input would go direct (RAW as it's known) through to vi and all screen output would come directly back, untouched, to the user.

这就是我要在C语言中实现的方式:

And this is how I would achieve it in C:

void main() {
    system("vi");
}

更新:

这可以达到预期的结果,但是a)仅限于Linux/OSX(不是什么大问题,但是可以跨平台使用会很好),b)是一个可怕的难题:

This achieves the desired result, but a) is limited to Linux / OSX (not that much of a problem, but would be nice to have it cross platform), and b) is a terrible 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();
        }
    }
}

推荐答案

system("vi")完全相同的完全是:

final ProcessBuilder p = new ProcessBuilder("vi");
p.redirectInput(Redirect.INHERIT);
p.redirectOutput(Redirect.INHERIT);
p.redirectError(Redirect.INHERIT);

p.start().waitFor();

(我知道这会延迟3年,但对于其他存在相同问题的人来说)

这篇关于在Java中运行交互式Shell程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 17:01
查看更多