这一定很简单,但我无法理解。
这是一个简单的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#
这是一种缓冲的问题? 有人可以帮我做一个继续的计划,请吗?
如果可以确定流是指交互设备 (例如终端),则标准输出流是行缓冲的,否则它是完全缓冲的,因此,有些情况下printf
不会刷新,即使它有一个换行符打印,像管道或重定向的输出;
> tst | tee file > tst > file
在printf()
fflush(stdout)
之后调用fflush(stdout)
将解决问题。
来自C99
第7.19.3
节的相关文本指出:
当一个数据流没有缓冲的时候,字符应该尽可能地从源头或目的地出现。 否则,字符可以积累并作为一个块被传送到主机环境或从主机环境传送。
当一个流被完全缓冲时,当缓冲区被填满时,字符被打算作为一个块被传输到主机环境或从主机环境传输。
当一个流是行缓冲的时候,当遇到一个换行符时,字符将作为一个块被传送到主机环境或从主机环境传送出去。
最初打开时,标准错误流没有被完全缓冲; 标准输入和标准输出流是完全缓冲的,当且仅当流可以被确定为不涉及交互设备时。
看来你的问题是stdout
被缓冲,并且不会在新行之后显示。 您可以通过在printf语句之后将其刷新来强制显示它:
fflush(stdout);
或者,您可以禁用缓冲:
setbuf(stdout, NULL);
此外,请注意stderr
没有被缓冲,您可以通过打印到stderr
而不是stdout
stderr
来检查问题是否是缓冲的。
正如你已经注意到,你也可以使用stdbuf
(更多信息与这个答案 )。