C:标准输出挂起 Linux 管道

3

我已经用C语言编写了一个简单的I/O回显程序,用于测试一个更大的真实程序中出现的问题。在这里,Linux FD重定向不起作用。

这个回显程序(也称为a.out)是:

#include <stdio.h>

int main(int argc, char **argv) {
  char buff[10];
  while (1) {
    if (fgets(buff, 10, stdin) == NULL) break;
    printf("PRINT: %s \n", buff);
  }
}

从Bash中,我这样运行它: ```sh 命令示例 ```
$ mkfifo IN OUT
$ # this is a method to keep the pipes IN and OUT opened over time
$ while :; do read; echo Read: $REPLY >&2; sleep 1; done <OUT >IN &
$ a.out >OUT <IN &

$ echo xyz >IN

没有任何输出:Bash while 循环无法从OUT读取。


让我们将此 a.out 与正常工作的cat进行比较:

$ mkfifo IN OUT
$ while :; do read; echo Read: $REPLY >&2; sleep 1; done <OUT >IN &
$ cat >OUT <IN &

$ echo xyz >IN
Read: xyz

这行最后的文字会被打印到标准错误控制台上。 cat的输出可以通过OUT传递到Bash while循环中,并在控制台上打印出来。
a.out有什么问题呢?


我一直在Bash中使用Linux管道来处理多个来源的数据。这些数据是随机复用的。即使一个单一的管道可以有多个目的地,但是这里的行为是不可预测的。 - davide
其实,不用在意我说的话,它没有任何意义! - Kerrek SB
如果我没记错的话,在将 stdout 重定向到管道后,IO 流将不再是行缓冲而是完全缓冲。您也可以使用 setbuf 将其更改为行缓冲。 - user339222
1个回答

5
尝试在printf(...)之后添加fflush(stdout)

我添加了fflush(stdout),但它仍然与以前的a.out完全相同。(对于编辑我表示抱歉) - davide
1
加上 fflush(stdout) 就可以在我的电脑上运行了(或者通过简单地压倒缓冲区,例如 seq 1 1000 > IN)。 - themel
哇,fflush() 实际上解决了这个问题。这是我的错,因为我太忙了,没有集中精力。并且借助它,我也修复了更大、实际的程序! - davide

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接