I am aware that STDOUT
is usually buffered by commands like mawk
(but not gawk
), grep
, sed
, and so on, unless used with the appropriate options (i.e. mawk --Winteractive
, or grep --line-buffered
, or sed --unbuffered
). But the buffering doesn't happen when STDOUT
is a terminal/tty, in which case it is line buffered.
Now, what I don't get is why STDOUT
is buffered outside of a loop send to a pipe, even though the final destination is the terminal.
A basic example :
$ while sleep 3; do echo -n "Current Time is ";date +%T; done | mawk '{print $NF}'
^C
Nothing happens for a long time, because mawk
seems to be buffering it's output.
I wasn't expecting that. mawk
's output is the terminal, so why is its STDOUT
buffered ?
Indeed, with the -Winteractive
option the output is rendering every 3 seconds :
$ while sleep 3; do echo -n "Current Time is ";date +%T; done | mawk -Winteractive '{print $NF}'
10:57:05
10:57:08
10:57:11
^C
Now, this behavior is clearly mawk
related, because it isn't reproduced if I use for example grep
. Even without its --line-buffered
option, grep
doesn't buffer its STDOUT
, which is the expected behavior given that grep
's STDOUT
is the terminal :
$ while sleep 3; do echo -n "Current Time is ";date +%T; done | grep Current
Current Time is 11:01:44
Current Time is 11:01:47
Current Time is 11:01:50
^C
awk
(= gawk) will show time at "3":apt install gawk
and do$ while sleep 3; do echo -n "Current Time is ";date +%T; done | awk '{print $NF}'
.... Info superuser.com/questions/75875/awk-mawk-nawk-gawk-whatgawk
never buffers (I said it in my first paragraph). But that's beside the point, I'm trying to understand whymawk
is buffering even whenSTDOUT
is tty (terminal). Or, in other words, why my| mawk
example behaves differently from my| grep
example in terms of buffering.