为什么即使是终端,mawk 的输出 (STDOUT) 也会被缓冲?

Che*_*tar 5 shell awk buffer stdout

我知道它STDOUT通常由mawk(但不是gawk)、grep、等命令缓冲sed,除非与适当的选项(即mawk --Winteractive、 或grep --line-buffered、 或sed --unbuffered)一起使用。但是当STDOUT是终端/tty时不会发生缓冲,在这种情况下它是行缓冲的。

现在,我不明白的是为什么 STDOUT在循环之外缓冲发送到管道,即使最终目的地是终端。

一个基本的例子:

$ while sleep 3; do echo -n "Current Time is ";date +%T; done | mawk '{print $NF}'
^C
Run Code Online (Sandbox Code Playgroud)

很长时间没有任何反应,因为mawk似乎正在缓冲它的输出。

我没想到。mawk的输出是终端,那么为什么它是STDOUT缓冲的?

实际上,使用该-Winteractive选项,输出每 3 秒渲染一次:

$ 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
Run Code Online (Sandbox Code Playgroud)

现在,这种行为显然是mawk相关的,因为如果我使用例如grep. 即使没有它的--line-buffered选项,grep也不会缓冲它的STDOUT,这是预期的行为,因为grep'sSTDOUT是终端:

$ 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
Run Code Online (Sandbox Code Playgroud)

Sté*_*las 12

并不是它在缓冲它的输出

mawk是我知道的唯一可以缓冲其输入的实用程序

另见https://github.com/ThomasDickey/original-mawk/issues/41#issuecomment-241070898

换句话说,在mawk它积累了一个充满输入的缓冲区之前,不会开始处理它的输入(更不用说打印任何内容,如果该处理涉及打印)。

您可以通过运行来验证它:

(echo 1; sleep 1; echo 2) | mawk '{system("echo "$1)}'
Run Code Online (Sandbox Code Playgroud)

可以使用-Winteractive选项禁用它。请注意,-Winteractive无论 的值如何,记录都是行RS