It’s a common problem. You write some shell command like:
$ tail -f /var/log/foo | egrep -v 'some|stuff' | sed | awk
and wonder why nothing is printed, even though you know some text has matched. The problem is that stdio is being buffered, and there’s a very good write-up of the problem here so I won’t repeat the technical background.
What I will provide though is how to fix it for common cases.
stdbuf
stdbuf is part of GNU coreutils, and is essentially an LD_PRELOAD hack which calls setvbuf() for an application. Thus it is a generic solution to the problem and can be used to fix most applications. Usage looks like this:
$ tail -f /var/log/foo | stdbuf -o0 app ...
which will disable output buffering for app, assuming it does not do something itself to reverse thesetvbuf() call. An example of a misbehaving application is mawk, below.
awk
GNU awk needs no modifications, that is it does not buffer when there is no controlling tty.
mawk however (the default awk in Debian/Ubuntu and possibly others) buffers output, and also does not seem to work with stdbuf. It does however provide a -Winteractive option which will turn off buffering.
$ tail -f /var/log/foo | gawk
or
$ tail -f /var/log/foo | mawk -Winteractive
sed
GNU sed provides the -u option which calls fflush(), thereby providing unbuffered output. You can also use stdbuf as above.
$ tail -f /var/log/foo | sed -u
or
$ tail -f /var/log/foo | stdbuf -o0 sed
grep
Similar to sed, GNU grep provides a specific option, --line-buffered, to disable buffering, or again you can use stdbuf.
$ tail -f /var/log/foo | grep --line-buffered
or
$ tail -f /var/log/foo | stdbuf -o0 grep
This article is copied from http://www.perkin.org.uk/posts/how-to-fix-stdio-buffering.html.
浙公网安备 33010602011771号