默认情况下,*nix 命令的 stdout 和 stdin 如果是在终端中是行缓冲,stderr 则是无缓冲。而这些标准输入输出如果是在管道中或重定向文件则是全缓冲。有时候使用管道处理数据的时候,并不希望管道后面的命令一直阻塞等待前一个的输出填满缓冲区刷新的时候才能处理,而是希望能即时看到数据。
有些命令提供了参数来设置缓冲模式,比如 tcpdump 可以使用 -l 参数来强制设置为行缓冲,awk、grep、sed 等也有这样的参数。但是也还是有很多命令行工具并没有提供这样的功能,这时候可以利用 stdbuf 命令来设置。
比如
stdbuf -oL tcpdump ... | grep ...
就可以把 tcpdump 的 stdout 设置为行缓冲,起到同样的效果。同样可以用 -i, -e 来设置 stdin 和 stderr 的缓冲模式。可以设置为 L 表示行缓冲,0 表示无缓冲,或者设置一个指定的缓冲区大小,如 4K 。这样无论命令是否支持设置缓冲模式都可以解决这些问题了。