【问题标题】:Why can't I start `bash -i` using ProcessBuilder in Java?为什么我不能在 Java 中使用 ProcessBuilder 启动 `bash -i`?
【发布时间】:2017-03-21 17:10:42
【问题描述】:

我正在尝试从 Java 应用程序运行命令 bash -i,因为我希望用户能够在一些工作中使用 shell,然后返回到 Java 应用程序。

我有这个测试代码:

import java.io.*;
public class exec {
        public static void main(String[] args) throws IOException, InterruptedException {
                ProcessBuilder b = new ProcessBuilder(args);
                b.redirectError(ProcessBuilder.Redirect.INHERIT);
                Process p = b.start();
                InputStream pout = p.getInputStream();
                PrintWriter pin = new PrintWriter(p.getOutputStream());
                Thread in = new Thread(() -> {
                        while (true) {
                                try {
                                        int i = System.in.read();
                                        if (i == -1) break;
                                        pin.write(i);
                                        pin.flush();
                                } catch (IOException e) {
                                        e.printStackTrace();
                                        break;
                                }
                        }
                        System.err.println("in finished");
                });
                Thread out = new Thread(() -> {
                        while (true) {
                                try {
                                        int i = pout.read();
                                        if (i == -1) break;
                                        System.out.write(i);
                                } catch (IOException e) {
                                        e.printStackTrace();
                                        break;
                                }
                        }
                        System.err.println("out finished");
                });
                out.start();
                in.start();
                p.waitFor();
        }
}

编译后,一切正常。我什至可以启动bash shell:

$ java exec date
ti 21.3.2017 19.03.25 +0200
out finished
^C$ java exec bash
date
ti 21.3.2017 19.03.30 +0200
^Cout finished

但是,当我尝试启动 bash -i shell 时,终端开始出现异常。

$ java exec bash -i
[1] + Stopped (tty input)        java exec bash -i
$ user@computer:/tmp$ fg
java exec bash -i
date   
date
ti 21.3.2017 19.05.21 +0200
user@computer:/tmp$ pwd  
pwd
[1] + Stopped (tty input)        java exec bash -i

Java 进程停止了,shell 又是sh,我想。编写fg 后,date 命令工作一次,但当我尝试pwd 时,Java 再次停止。

有什么办法可以让这个工作吗?我想要的是从 Java 程序启动一个正常的交互式 bash 提示符。

【问题讨论】:

  • bash 正在从其附加的终端读取,而不是从标准输入读取,因此您的 processbuilder 设置没有帮助
  • @AndrewMcGuinness 好的。有什么办法可以让这个工作吗?我可以指定附加到终端的是bash 进程,而不是Java?

标签: java linux shell tty


【解决方案1】:

看来ProcessBuilder 方法inheritIO 可以满足我的要求。

ProcessBuilder b = new ProcessBuilder(args);
b.inheritIO();
Process p = b.start();

【讨论】:

    猜你喜欢
    • 2011-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    相关资源
    最近更新 更多