Search code examples
linuxshellawkbufferstdout

Why is mawk's output (STDOUT) buffered even though it is the terminal?


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

Solution

  • I got the answer here : https://unix.stackexchange.com/questions/655796/why-is-mawks-output-stdout-buffered-even-though-it-is-the-terminal#answer-655807

    mawk is buffering its INPUT, which confused me (see also https://github.com/ThomasDickey/original-mawk/issues/41#issuecomment-241070898)

    Carefully reading mawk's manpages gives the answer too : -W interactive sets unbuffered writes to stdout and line buffered reads from stdin.