管道发球时标准输出的力线缓冲管道发球时标准输出的力线缓冲(Force line-buffering

2019-06-14 14:51发布

通常, stdout是行缓冲。 换句话说,只要你printf参数以换行符结束,你可以期望瞬间打印的线。 这似乎不是使用管道重定向到何时举行tee

我有一个C ++程序, a ,输出字符串,总是\n封端,到stdout

当它本身(运行./a ),一切都打印正确,并在合适的时机,符合市场预期。 但是,如果我管它tee./a | tee output.txt ),它不直到它退出,这违背了使用的目的打印任何tee

我知道我可以通过添加修复它fflush(stdout)在C ++程序每一次印制操作之后。 但有一个更清洁,更简单的方法? 是否有一个命令,我可以运行,例如,这将迫使stdout进行行缓冲,使用管道甚至当?

Answer 1:

尝试unbuffer这是一部分expect包。 您可能已经在系统上。

在你的情况,你会使用这样的:

./a | unbuffer -p tee output.txt

-p是用于管道模式,其中非缓冲从stdin读取和它在自变量的其余传递给命令)



Answer 2:

你可以尝试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 e.g.) 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.

你没有运行stdbuftee ,你运行它a ,所以这应该不会影响你,除非你设置的缓冲a的流在a的来源。

此外, stdbuf 不是 POSIX,但GNU-的coreutils的一部分。



Answer 3:

你也可以尝试使用一个伪终端执行你的命令script命令(应执行行缓冲输出管道)!

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

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



Answer 4:

您可以使用从setlinebuf与stdio.h中。

setlinebuf(stdout);

这应更改为“行缓冲”的缓冲。

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



Answer 5:

如果您使用C ++流类代替,每一个std::endl一个隐含冲洗。 使用C风格的印花,我觉得你建议的方法( fflush()是唯一的出路。



文章来源: Force line-buffering of stdout when piping to tee