【问题标题】:using tee with continuous output of a C program将 tee 与 C 程序的连续输出一起使用
【发布时间】:2014-12-31 12:28:49
【问题描述】:

一定很简单,但我听不懂。

这是一个写入标准输出的简单 C 程序:

root@oceanLondon:~/tst# cat tst.c
#include <stdio.h>
#include <unistd.h>

int
main(int argc, char **argv)
{
        for (; ;) {
                printf("Hello world!\n");
                sleep(1);
        }
        return 0;
}

现在,如果我想将输出写入我的屏幕和文件:

root@oceanLondon:~/tst# ./tst |tee file

它只是不起作用,我有空屏幕和空文件​​。

如果我执行的程序退出,那么它可以完美运行,例如

root@oceanLondon:~/tst# ls |tee file
Makefile
file
qq
tst
tst.c
tst.o
root@oceanLondon:~/tst# cat file
Makefile
file
qq
tst
tst.c
tst.o
root@oceanLondon:~/tst#

这是某种缓冲问题吗?有人可以帮我做一个延续计划吗?

【问题讨论】:

  • 如果你尝试fflush(stdout);?
  • @fredtantini:那么它确实有效。真的很简单。谢谢 - 请随时将其发布为答案。
  • 似乎有一些有用的答案here。 (我现在不在 Linux 机器上,所以无法试用。)
  • @fredtantini 作为这个问题的唯一答案已被删除,也许你应该发布一个。
  • 标准输出在直接到终端时通常是行缓冲的。当它进入管道时,它通常是完全缓冲的。您可以在每次迭代中使用fflush(),也可以调用setvbuf() 使标准输出行显式缓冲。

标签: c linux bash tee


【解决方案1】:

如果可以确定流是指交互式设备(例如终端),则标准输出流是行缓冲的,否则它是完全缓冲的,因此,在某些情况下printf 没有' t 刷新,即使它有一个要打印的换行符,如管道或重定向输出;

> tst | tee file
> tst > file

printf() 之后调用fflush(stdout) 将解决问题。

来自C99 部分7.19.3 的相关文字指出;

当一个流没有缓冲时,字符应该从 尽快到达源头或目的地。否则 字符可以累积并传输到主机或从主机传输 环境作为一个块。

当一个流被完全缓冲时,字符应该是 当缓冲区作为块传输到主机环境或从主机环境传输 充满。

当流被行缓冲时,字符旨在 当换行时作为块传输到主机环境或从主机环境传输 遇到字符。

最初打开时,标准错误流没有完全缓冲; 标准输入和标准输出流是完全缓冲的,如果 并且仅当可以确定流不引用 交互式设备。

【讨论】:

  • 您的回答似乎与您的报价相矛盾。 (答案的第一句中缓冲的行,引用的最后一句中的完全缓冲
  • @ace,你说得对,我修好了。非常感谢!
【解决方案2】:

您的问题似乎是stdout 被缓冲并且在新行之后没有显示。您可以通过在 printf 语句之后刷新它来强制显示它:

fflush(stdout); 

或者,您可以禁用缓冲:

setbuf(stdout, NULL);

另外,请注意stderr 没有缓冲,您可以通过打印到stderr 而不是stdout 来检查问题是否是缓冲的。

如您所见,您也可以使用stdbuf(更多信息请使用this answer)。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-23
  • 1970-01-01
  • 1970-01-01
  • 2019-07-08
  • 2016-10-02
  • 2011-05-20
  • 2022-11-05
相关资源
最近更新 更多