强制程序在redirect时刷新其标准输出

我有一个封闭的源程序,打印输出到标准输出。 我需要parsing输出。 所以我redirect输出到fifo(从我可以读取在父进程分叉和执行二进制)使用dup2,然后执行该程序。 问题是文件中的fprintf调用被缓冲,因为它正在写入一个文件。

在调用exec之前,我尝试在标准输出上用_IONBF调用setvbuf。 但问题依然存在。

为什么setvbuf在我的情况下没有帮助?

我怎样才能强制输出得到刷新?

Solutions Collecting From Web of "强制程序在redirect时刷新其标准输出"

setvbuf()没有什么区别,因为它改变了C运行时库的一部分的状态,而不是OS的一部分。 当新进程开始运行时,它的C运行时库将被重新初始化(就是说,如果它使用CRT的话)!

我所听说的解决这个问题的唯一方法是以某种方式伪造一个终端。 这是因为如果大多数CRT库相信它们被连接到一个交互式终端(默认情况下,在Unix世界中:如果isatty()在文件描述符上返回true),默认情况下只执行行缓冲,否则它们将缓冲在较大的块8Kb左右)。

这个工具看起来是一个很好的开始。 (借鉴一个应用程序的评论, 认为它的stdin是交互式的,而不是一个管道 ,有其他有用的信息。)

我猜你在你的程序中有这样的东西(你可以重现这个测试,我在这里称之为isatty

 #include <stdio.h> #include <unistd.h> const char* m1 = "%d: %sa TTY\n"; void isTty(FILE* f) { int fno = fileno(f); printf(m1, fno, (isatty(fno)) ? "is" : "is NOT"); } int main(int argc, char* argv[]) { isTty(stdin); isTty(stdout); } 

例如,如果你运行它

 $ ./isatty 0: is a TTY 1: is a TTY $ ./isatty > isatty.out $ cat isatty.out 0: is a TTY 1: is NOT a TTY $ ./isatty > isatty.out < /dev/null $ cat isatty.out 0: is NOT a TTY 1: is NOT a TTY 

现在,如果您创建一个expect脚本isatty.expect (如果未安装,请安装您的发行版)

 #! /usr/bin/expect -f spawn "./isatty" expect 

并运行它

 $ ./isatty.expect spawn ./isatty 0: is a TTY 1: is a TTY 

要么

 $ ./isatty.expect > isatty.out $ cat isatty.out spawn ./isatty 0: is a TTY 1: is a TTY 

unbuffer工具可以帮助解决这个问题:

它是expect-dev的一部分,可以在ubuntu上安装

 sudo apt-get install expect-dev 

使用它类型:

 unbuffer ls > log.txt