Reputation: 28384
If I execute
$ echo XXX | grep XXX
I immediately see the XXX
output, because, I understand, there is an EOF passed to grep
.
However, if I do something like this,
cat <(yes 'a' | head -c 4090) /dev/stdin > /dev/stdout | sed ';' | grep XXX
and then hit XXXEnter, I don't get any output yet. I have to enter 3 more bytes, e.g. via hitting Enter 3 more times, to get the output.
This reveals that grep
is holding on to 4096 character before flushing the output.
However, it appears that having that dummy sed ';'
process in the middle is necessary to observe this behavior. In other words, if the pipe was just
cat <(yes 'a' | head -c 4090) /dev/stdin > /dev/stdout | grep XXX
then the output would be visible upon pressing XXXEnter.
Where does this difference stem from?
Upvotes: 2
Views: 58
Reputation: 140880
This reveals that grep is holding on to 4096 character before flushing the output.
No, that reveals that sed is holding the characters. You can use sed -u
to make it unbuffered.
What determines whether grep buffers the output or not?
Typically in prevalent most cases whether the standard output file descriptor refers to a terminal device or not. isatty(1)
returns true -> output is line buffered, isatty(1)
return false -> output is fully buffered.
See https://www.gnu.org/software/libc/manual/html_node/Buffering-Concepts.html :
Newly opened streams are normally fully buffered, with one exception: a stream connected to an interactive device such as a terminal is initially line buffered.
Also I find those /dev/stdin >/dev/stdout
confusing. Check
cat <(yes 'a' | head -c 4090) <(sleep 1; echo XXX; sleep 1; echo XXX) | sed ';' | grep XXX
vs
cat <(yes 'a' | head -c 4090) <(sleep 1; echo XXX; sleep 1; echo XXX) | sed -u ';' | grep XXX
Upvotes: 4