关于io:使用Java 6中继承的stdin / stdout / stderr启动进程

关于io:使用Java 6中继承的stdin / stdout / stderr启动进程

Starting a process with inherited stdin/stdout/stderr in Java 6

如果我通过Java的ProcessBuilder类启动进程,则可以完全访问该进程的标准输入,标准输出和标准错误流,如Java InputStreamsOutputStreams。 但是,我找不到将这些流无缝连接到System.inSystem.outSystem.err的方法。

可以使用redirectErrorStream()来获取包含子流程的标准输出和标准错误的单个InputStream,然后循环遍历并通过我的标准输出将其发送出去,但是我找不到一种方法来让它 用户输入流程,就像我使用C system()调用时可以输入的那样。

Java SE 7发行时似乎有可能实现—我只是想知道现在是否有解决方法。 如果子进程中isatty()的结果进行了重定向,则奖励积分。


您将需要将Process输出,err和输入流复制到System版本。 最简单的方法是使用Commons IO包中的IOUtils类。 复制方法看起来就是您所需要的。 复制方法调用将需要在单独的线程中。

这是基本代码:

1
2
3
4
5
6
7
8
9
10
11
// Assume you already have a processBuilder all configured and ready to go
final Process process = processBuilder.start();
new Thread(new Runnable() {public void run() {
  IOUtils.copy(process.getOutputStream(), System.out);
} } ).start();
new Thread(new Runnable() {public void run() {
  IOUtils.copy(process.getErrorStream(), System.err);
} } ).start();
new Thread(new Runnable() {public void run() {
  IOUtils.copy(System.in, process.getInputStream());
} } ).start();

John答案的一种变体,可以编译,不需要您使用Commons IO:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private static void pipeOutput(Process process) {
    pipe(process.getErrorStream(), System.err);
    pipe(process.getInputStream(), System.out);
}

private static void pipe(final InputStream src, final PrintStream dest) {
    new Thread(new Runnable() {
        public void run() {
            try {
                byte[] buffer = new byte[1024];
                for (int n = 0; n != -1; n = src.read(buffer)) {
                    dest.write(buffer, 0, n);
                }
            } catch (IOException e) { // just exit
            }
        }
    }).start();
}


对于System.in,请使用以下pipein()而不是pipe()

1
pipein(System.in, p.getOutputStream());

实现方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private static void pipein(final InputStream src, final OutputStream dest) {

    new Thread(new Runnable() {
        public void run() {
            try {
               int ret = -1;
               while ((ret = System.in.read()) != -1) {
                  dest.write(ret);
                  dest.flush();
               }
            } catch (IOException e) { // just exit
            }
        }
    }).start();

}


推荐阅读

    linux查看命令行进程?

    linux查看命令行进程?,系统,软件,信息,状态,进程,名称,实时,命令,数据,电脑,

    linux启动蓝牙命令?

    linux启动蓝牙命令?,设备,手机,系统,蓝牙,电脑,管理,网络,密码,通讯,信息,Lin

    linux启动进去命令行?

    linux启动进去命令行?,系统,工具,首页,电脑,终端,材料,密码,命令,快捷键,窗

    linux启动显示命令行?

    linux启动显示命令行?,系统,密码,终端,状态,首页,情况,基础,电脑,信息,工具,l

    linux命令行启动登陆?

    linux命令行启动登陆?,密码,系统,电脑,地址,设计,代码,项目,连续,工具,庞大,L

    linux的u盘启动命令?

    linux的u盘启动命令?,系统,电脑,工具,信息,软件,网上,名称,工作,设备,通用,从

    linux防火墙命令启动?

    linux防火墙命令启动?,系统,状态,管理,密码,服务,工具,防火墙,网络,信息,软

    linux启动显示命令行?

    linux启动显示命令行?,系统,密码,终端,状态,首页,情况,基础,电脑,信息,工具,l

    linux命令查找进程?

    linux命令查找进程?,系统,名称,软件,状态,进程,电脑,信息,命令,材料,数据,怎

    linux命令校验进程?

    linux命令校验进程?,服务,系统,情况,状态,异常,进程,命令,管理,检测,平台,Lin

    linux中终止进程命令?

    linux中终止进程命令?,系统,进程,信息,管理,命令,代码,传播,状态,名称,数字,l

    linux关闭子进程命令?

    linux关闭子进程命令?,系统,进程,名称,软件,管理,传播,命令,信息,状态,数字,l

    linux启动实例的命令?

    linux启动实例的命令?,密码,软件,环境,系统,管理,情况,工具,数据,设备,位置,l

    linux退出启动命令行?

    linux退出启动命令行?,系统,状态,档案,平台,命令,环境,模式,终端,程序,编辑,l

    关闭启动linux的命令?

    关闭启动linux的命令?,服务,系统,命令,代码,手机,软件,密码,管理,信息,状态,l

    linux进程运行命令?

    linux进程运行命令?,系统,工作,状态,地址,信息,进程,基础,命令,管理,软件,lin

    进程管理linux命令?

    进程管理linux命令?,系统,管理,地址,状态,情况,简介,工具,网络,分析,软件,lin

    linux中启动服务命令?

    linux中启动服务命令?,服务,系统,命令,信息,工作,设备,网络,标准,名称,密码,l

    linux永久启动命令?

    linux永久启动命令?,系统,服务,密码,软件,工具,电脑,位置,环境,状态,发行,lin

    linux命令行启动软件?

    linux命令行启动软件?,系统,工具,软件,位置,密码,电脑,首页,代码,环境,地方,l