我遇到了cat
命令输出完全缓冲的一行。这是什么意思?
答案 0 :(得分:5)
Online C11 standard,7.21.3 / 3:
当流 unbuffered 时,字符应尽快从源或目的地出现。否则,可以将字符作为块累积并发送到主机环境或从主机环境发送。当流完全缓冲时,当填充缓冲区时,字符将作为块传输到主机环境或从主机环境传输。当流行缓冲时,当遇到换行符时,字符将作为块传输到主机环境或从主机环境传输。此外,当填充缓冲区,在无缓冲流上请求输入时,或者在需要从主机环境传输字符的行缓冲流上请求输入时,字符旨在作为块传输到主机环境。 。对这些特性的支持是实现定义的,可能会受到
setbuf
和setvbuf
函数的影响。
7.21.3 / 7:
在程序启动时,预定义了三个文本流,无需明确打开 - 标准输入(用于读取常规输入),标准输出(用于写入常规输出) ,和标准错误(用于编写诊断输出)。最初打开时,标准错误流未完全缓冲;当且仅当可以确定流不参考交互设备时,标准输入和标准输出流是完全缓冲的。
答案 1 :(得分:2)
无缓冲输出将输入文件中的字节写入标准 每次读取都没有延迟输出。
全缓冲输出首先在读取时按顺序读取整个文件并将其存储在缓冲区中并显示缓冲区的完成情况。
使用-u选项可以避免它。
答案 2 :(得分:2)
[我在示例中使用Perl来简化和简化再现,但我所说明的概念并非特定于Perl。 C的工作方式相同。]
缓冲指示写入文件句柄的内容被刷新(发送)到OS的频率。比较以下两个命令的行为:
# With buffering (default)
perl -e'$|=0; print "a"; sleep(2); print "b\n";'
# Without buffering
perl -e'$|=1; print "a"; sleep(2); print "b\n";'
通常,缓冲区仅在填满时才刷新。遇到换行符时也会刷新行缓冲输出。比较:
perl -e'print "a"; sleep(2); print "b\n";'
perl -e'print "a\n"; sleep(2); print "b\n";'
大多数程序都使用块缓冲。但是,当它连接到终端时,它们通常会切换到stdout的行缓冲。比较:
# Perl's STDOUT is line-buffered when connected to a terminal.
perl -e'print "a\n"; sleep(2); print "b\n";'
# Perl's STDOUT is fully buffered when connected to a pipe.
perl -e'print "a\n"; sleep(2); print "b\n";' | cat
# unbuffer uses pseudo-ttys to fool a program into thinking it's connected to a terminal.
unbuffer perl -e'print "a\n"; sleep(2); print "b\n";' | cat