【问题标题】:Why does this Java process suspend after running bash as a subprocess?为什么这个 Java 进程在将 bash 作为子进程运行后会挂起?
【发布时间】:2016-01-13 14:13:44
【问题描述】:

如果我从 bash 编译并运行以下 Java 程序:

public class BashSuspend {

    public static void main(String[] args) throws Exception {
        Process process = new ProcessBuilder("bash -i -c ls".split(" "))
                .redirectInput(ProcessBuilder.Redirect.INHERIT)
                .redirectOutput(ProcessBuilder.Redirect.INHERIT)
                .redirectError(ProcessBuilder.Redirect.INHERIT).start();
        process.waitFor();
        System.in.read();
    }
}

我看到一些奇怪的行为:

matt@Overmind:~/bash-suspend$ java BashSuspend 
BashSuspend.class  BashSuspend.java

[1]+  Stopped                 java BashSuspend
matt@Overmind:~/bash-suspend$

为什么 Java 进程在将 bash 作为子进程运行后会挂起?

(我在 Ubuntu 15.10 上运行 openjdk 版本“1.8.0_66-internal”。)

【问题讨论】:

    标签: java bash process


    【解决方案1】:

    您的程序正在等待输入,只有在前台运行时才能执行此操作。

    我不会等待您忽略的输入,而是将其删除或使用其他方法。

    【讨论】:

    • 程序应该一直在前台运行。它可能会在等待子进程完成或从标准输入读取时阻塞,但这与暂停不同。
    【解决方案2】:

    您收到 [1]+ Stopped 的原因是:

    bash -i
    

    在交互模式下运行bash。删除 -i 选项来解决这个问题:

    new ProcessBuilder("bash -c ls".split(" "))
    

    根据man bash

    -i        If the -i option is present, the shell is interactive.
    

    您还需要注释掉System.in.read(); 以避免让您的程序继续运行(它只是在等待输入)。

    在您收到Stopped 错误后,只需在我的答案中添加更多信息,您可以运行:

    jobs -l
    

    列出后台运行的作业,它将显示如下内容:

    [1]+ 71598 Stopped (tty input): 21 java BashSuspend
    

    这是由于您使用了System.in.read();,它只是在等待交互式外壳中的输入,而该交互式外壳没有附加tty,因此它被停止了。

    【讨论】:

    • 我对为什么运行“bash -i”会导致 java 进程挂起感兴趣。
    • 因为ProcessBuilder 并没有真正运行交互式bash。交互式bash 表示您通常使用的bash 登录shell,它附加了tty,而这里我们没有附加任何tty
    • 我不这么认为:如果你只是运行bash -i,那么 bash 会正常启动,并附加一个 tty。无论如何,这并不能解释为什么父 java 进程被挂起。
    • 从命令行运行 bash -i 与从 Java 代码运行 bash -i 不同,因为您在 shell 中已经附加了 tty
    • 不,如果你从 Java 中运行 bash -i 作为子进程,你仍然有一个附加的 tty。
    猜你喜欢
    • 1970-01-01
    • 2011-05-17
    • 1970-01-01
    • 2014-03-22
    • 1970-01-01
    • 1970-01-01
    • 2015-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多