Bourne | Ash |  #!  | find | ARG_MAX | Shells | whatshell | portability | permissions | UUOC | ancient | - | ../Various | HOME
"$@" | echo/printf | set -e | test | tty defs | tty chars | $() vs ) | IFS | using siginfo | nanosleep | line charset | locale


Unwanted Buffering

2017-03-29 (see recent changes)

Other documents:

Avoiding "extraneous" buffering in pipelines

If you build a chain of filters, the throughput may drop down unexpectedly slow:

    while sleep 0.1; do date; done|grep .         # immediate output each tenth of a second
    while sleep 0.1; do date; done|grep .|grep .  # delayed output in big chunks, about every 10 seconds

A real world example is searching growing logfiles with tail -f feeding several invocations of grep.

The explanation can be found in the C library, which provides different output buffering methods: unbuffered, line buffeed and block (or fully) buffered. See setbuf(3).
There is no such buffering if write(2) is used instead of library functions like printf(3).
The C library offers buffering simply for performance reasons. The highest throughput is achieved with block buffering due to the lowest overhead.
The slower line buffering might only be used if a command is directly connected to a tty, where immediate output is expected.
In a pipeline, the full buffering usually happens in blocks of PIPE_BUF bytes. Common values are 4096 bytes (4K) or 5120 bytes (10 blocks of 512 bytes).

    $ cpp<<EOF|egrep -v '^#|^$'
    #include <limits.h>
    PIPE_BUF
    EOF

    4096 

Keep in mind that it's not about the pipeline itself, but the buffering method, if the utility doesn't see a TTY.

There's no universal way to avoid the buffering of a utility. However, here are some possible options:


<http://www.in-ulm.de/~mascheck/various/buffering/>

Sven Mascheck