我可以禁用 tr 的缓冲吗

我可以禁用 tr 的缓冲吗

tr似乎缓冲其输入,以便该命令LongRunningCommand|tr \\n ,仅在 LongRunningCommand 的输入积累了几千字节后才开始生成输出。

有没有办法强制tr停止此缓冲或任何其他可以在不缓冲的情况下用其他字符替换换行符的命令?


PS我已经尝试过前两个建议关闭管道中的缓冲没有成功。

答案1

命令通常不缓冲其输入。他们会对read()一个大块执行 a ,但是当从管道读取时,如果管道中没有那么多字节,read()系统调用将返回尽可能多的字符,并且应用程序通常会使用它(如果可以的话) 。

一个值得注意的例外是,mawk它将一直持续read(),直到输入缓冲区已满。

应用程序确实缓冲它们的输出(标准输出)不过。通常的行为是,如果输出到 tty,那么缓冲将是逐行的(也就是说,它不会开始写入标准输出,直到它有一个完整的行要输出,或者对于非常多的块来说是满的)长行),而对于所有其他类型的文件,缓冲是按块进行的(也就是说,只有在有一个块可写满时才会开始写入(例如 4KiB/8KiB...取决于软件和系统) ))。

因此,在您的情况下LongRunningCommand,可能按块缓冲其输出(因为其输出是管道而不是 tty),并且tr可能按行缓冲其输出,因为其输出可能是终端。

但是,由于您从其输出中删除了每个换行符,因此它永远不会输出一行,因此缓冲将按块进行。

所以在这里您要禁用LongRunningCommand和 的缓冲tr。在 GNU 或 FreeBSD 系统上:

stdbuf -o0 LongRunningCommand | stdbuf -o0 tr '\n' ,

请注意,如果您想用逗号连接行,更好的方法是使用paste -sd , -.这样,输出将由换行符终止(您可能仍然需要禁用缓冲)。

答案2

要将换行符替换为",",您可以运行

awk '{ printf "%s,", $0 }'

当输出到终端时,GNU awk ( gawk) 和 Solaris将在 stdin 上使用行缓冲运行,而不会缓冲 stdout。nawk如果您的 awk 是mawk,这发生在 Ubuntu 上,您可以为其提供-W interactive获得相同缓冲行为的选项。

相关内容