修改“... | tee -a out.txt”以实时流式传输输出,而不是在完成时?

Bla*_*ies 3 bash stdout stderr output

我需要在文件上输出命令的输出。假设我的命令是zip -r zip.zip directory,我需要将(这些选项中的任何一个都可以)附加/写入文件(假设out.txt)。我zip zip.zip directory | tee -a out.txt到目前为止,但它似乎不起作用,它只是在命令结束时写入整个输出......我怎样才能做到这一点?

谢谢 ;)

Cha*_*ffy 11

背景(即。为什么?)

重定向是即时的——当您运行somecommand | tee -a out.txt,somecommand设置为将其标准输出直接发送到tee命令,该命令由其文档定义为无缓冲,从而尽快将其输入上可用的任何内容写入其指定的输出接收器。同样,somecommand >out.txtsomecommand被写入out.txt字面上之前它甚至开始。

什么是不能直接被冲洗缓冲输出。

也就是说:标准 C 库和大多数其他工具/语言在 stdout 上缓冲输出,将小写组合成大写。这通常是可取的,因为减少了进出内核空间(“上下文切换”)的调用次数,有利于进行较少数量的更高效、更大的写入。

所以,你的程序是不是真的等到它退出来写它的输出-但它正在等待(可能的32KB,64KB或,或其他),直到它的缓冲区已满。如果它从不产生那么多输出,那么它只会在关闭输出流时被刷新。


解决方法(如何? - GNU 版本)

如果您在 GNU 平台上,并且您的程序将其文件描述符保留为找到它们的方式,而不是尝试显式配置缓冲,则可以使用该stdbuf命令来配置缓冲,如下所示:

stdbuf -oL somecommand | tee -a out.txt
Run Code Online (Sandbox Code Playgroud)

将 stdout ( -o)定义为L运行时行缓冲 ( ) somecommand


解决方法(如何? - 期望版本)

或者,如果您已expect安装,则可以使用unbuffer它包含的帮助程序:

unbuffer somecommand | tee -a out.txt
Run Code Online (Sandbox Code Playgroud)

...它实际上会模拟 TTY(就像expect那样),获得somecommand与直接连接到控制台时相同的非缓冲行为。