完全按照写入的方式读取外部进程的交错 stdout 和 stderr

Read an external process's interleaved stdout and stderr exactly as they are written

我正在使用 ProcessBuilder 启动 bash 进程。 我正在执行的命令写入 stdout 和 stderr。 到目前为止,我还没有找到按照命令打印的顺序获取 stdout 和 stderr 的方法,以及如果我在 Java.

之外执行命令时它们的显示方式

假设该过程有这样的输出:

我想知道这些行的确切顺序。所以例如。 B写在C之前A之后

中提供的答案似乎适用于某些人,但可能无法保证在所有平台上都适用? 我在 Ubuntu 20.04.

上使用 OpenJDK 64 位服务器 VM AdoptOpenJDK(构建 11.0.8+10,混合模式)

到目前为止我尝试过的:

John Kugelman 的评论为我指明了正确的方向。非常感谢!

缓冲不会发生在 Java 端,而是将 stdout 和 stderr 传送到另一个程序的结果。在本例中是 JVM。

it becomes full buffered. stderr, on the other hand, stays line buffered even when piped.

所以我们想改变外部进程调用的缓冲行为。

我选择了https://unix.stackexchange.com/a/61833/274368中描述的script路线。 我的代码现在看起来像这样:

String command = "script -q -c \"my-command\" /dev/null";
ProcessBuilder processBuilder = fs.runInShell(command, args.toArray(new String[args.size()]));
processBuilder.directory(workingDirectory);
processBuilder.redirectErrorStream(true);
Process process = processBuilder.start();
try (BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
    String message = input.lines().collect(Collectors.joining(System.lineSeparator()));
    // ...
}

其中 message 以正确的顺序包含来自 stderr 和 stdout 的所有行。