Search code examples
unixbufferpipestdouttee

Force line-buffering of stdout in a pipeline


Usually, stdout is line-buffered. In other words, as long as your printf argument ends with a newline, you can expect the line to be printed instantly. This does not appear to hold when using a pipe to redirect to tee.

I have a C++ program, a, that outputs strings, always \n-terminated, to stdout.

When it is run by itself (./a), everything prints correctly and at the right time, as expected. However, if I pipe it to tee (./a | tee output.txt), it doesn't print anything until it quits, which defeats the purpose of using tee.

I know that I could fix it by adding a fflush(stdout) after each printing operation in the C++ program. But is there a cleaner, easier way? Is there a command I can run, for example, that would force stdout to be line-buffered, even when using a pipe?


Solution

  • Try unbuffer (man page) which is part of the expect package. You may already have it on your system.

    In your case you would use it like this:

    unbuffer ./a | tee output.txt

    The -p option is for pipeline mode where unbuffer reads from stdin and passes it to the command in the rest of the arguments.