哪些命令需要添加“stdbuf”前缀?

哪些命令需要添加“stdbuf”前缀?

当我有一个长时间运行的 Bash 命令管道时,由于 I/O 缓冲,我经常看不到任何生命迹象。我在网上发现可以使用 禁用缓冲stdbuf。显示的示例这里是:

tail -f access.log | stdbuf -oL cut -d aq aq -f1 | uniq

但是,我不清楚管道中的哪些命令需要以命令为前缀stdbuf。因此我将它添加到每个命令中。如果没有缓冲,我可能会这样做:

cd ~/tmp
stdbuf -i0 -o0 -e0 find /i \! -type d | \
stdbuf -i0 -o0 -e0 sed -u -n -e \
's=.*\<\(\([A-Z_a-z0-9.-]\+\)/\2/\).*=& \1=p' \
2>&1 | stdbuf -i0 -o0 -e0 tee find.out

这使得我的代码在认知意义上非常嘈杂。

如何决定哪些命令需要前缀stdbuf

答案1

看不到“实时”输出的问题在于标准输出的输出缓冲。输入缓冲不是问题,而且标准错误默认情况下是不缓冲的。所以你可以删除-i0-e0选项。禁用输入缓冲实际上可能会适得其反,因为它可能会减慢程序速度。

然后,由于问题在于处理写入除了在终端中,管道的最后一个命令通常不会缓冲其输出。 (除非您将其输出重定向到文件并通过另一个程序查看该文件。)

然后,如果一个程序确实有一个专门的选项来禁用缓冲,就像grep --line-buffered在 GNU grep 中一样,那么就没有理由使用stdbuf除此之外的选项。sed -u也意味着在 GNU sed 中禁用缓冲。另外,egtail -f不会缓冲其输出,因为实时查看它是重点。

所以,我想这应该这样做:

stdbuf -o0 find /i \! -type d | \
 sed -u -n -e 's=.*\<\(\([A-Z_a-z0-9.-]\+\)/\2/\).*=& \1=p' 2>&1 | \
 tee find.out

(尽管如此,我想知道find缓冲是否足够慢而导致严重问题。)

相关内容