为什么如果a | b崩溃,b可能无法接收来自a的所有已生成的输出

时间:2018-02-12 19:17:39

标签: bash

考虑在bash中执行a | b,如果a执行Segmentation faultb(例如cat)可能只获得部分数据。我尝试了很多进程,行为不稳定,偶尔得到a的整个输出,但大多数情况下它被截断,即最后5-10行没有显示。同时,如果只运行a,没有管道,只输出到终端,所有数据总是显示在终端中。

以下是问题,为什么会发生这种情况,以及如何确保最正确的流程(b)获取最左边(a)能够在崩溃之前生成的所有数据。

我们假设我可以修改两个程序的源代码。

在我的情况下,我使用过用C和Node.js编写的程序,行为代表两种语言,所以我不确定在标签中使用哪种语言,它是否与C中的标签相关或Nodejs

1 个答案:

答案 0 :(得分:1)

默认情况下,在glibc中,stdout是'行缓冲' (连接到终端时写入发生在行尾),并且“完全缓冲”#39; (写入在缓冲区已满时发生)否则(例如,当连接到管道时)。

由于管道的缓冲区大小通常在4kB到64kB之间,因此a的输出在馈送到b之前比缓存大小更多,而不是写入终端。 / p>

要在连接到管道时取消缓存a的输出,您可以使用these techniques之一:

  • expect命令unbuffer
  • stdbuf -i0 -o0 -e0 command
  • socat