pipe道到三通时,强制标准输出缓冲

通常, stdout是行缓冲的。 换句话说,只要你的printf参数以一个换行符结束,你可以期望行被立即打印。 这在使用pipe道redirect到tee时似乎不成立。

我有一个C ++程序, a输出string,总是\n terminated,到stdout

当它自己运行( ./a )时,正如所期望的那样,所有东西都可以正确打印。 但是,如果我将它input到tee./a | tee output.txt )中,它将不会打印任何东西,直到退出为止,这会破坏使用tee的目的。

我知道我可以通过在C ++程序中的每个打印操作之后添加一个fflush(stdout)来修复它。 但是,有没有更简单,更简单的方法? 是否有一个命令我可以运行,例如,即使在使用pipe道时强迫stdout被行缓冲?

试试unbuffer这是expect包的一部分。 您的系统上可能已经有了它。

你可以试试stdbuf

 $ stdbuf -o 0 ./a | tee output.txt 

(大)手册页的一部分:

  -i, --input=MODE adjust standard input stream buffering -o, --output=MODE adjust standard output stream buffering -e, --error=MODE adjust standard error stream buffering If MODE is 'L' the corresponding stream will be line buffered. This option is invalid with standard input. If MODE is '0' the corresponding stream will be unbuffered. Otherwise MODE is a number which may be followed by one of the following: KB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y. In this case the corresponding stream will be fully buffered with the buffer size set to MODE bytes. 

请记住这一点,但:

 NOTE: If COMMAND adjusts the buffering of its standard streams ('tee' does for eg) then that will override corresponding settings changed by 'stdbuf'. Also some filters (like 'dd' and 'cat' etc.) dont use streams for I/O, and are thus unaffected by 'stdbuf' settings. 

你不是在tee上运行stdbuf ,而是在a上运行stdbuf ,所以这不应该影响你,除非你设置缓冲stream的源码。

而且, stdbuf 不是 POSIX,而是GNU-coreutils的一部分。

您也可以尝试使用script命令在伪terminal执行您的命令(这应该强制线路缓冲输出到pipe道)!

 script -q /dev/null ./a | tee output.txt # Mac OS X, FreeBSD script -c "./a" /dev/null | tee output.txt # Linux 

请注意, script命令不传播包装命令的退出状态。

你可以使用stdio.h中的setlinebuf。

 setlinebuf(stdout); 

这应该改变缓冲“行缓冲”。

如果你需要更多的灵活性,你可以使用setvbuf。

如果使用C ++stream类,则每个std::endl 都是一个隐式的flush。 使用C风格的打印,我认为你所build议的方法( fflush() )是唯一的方法。