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

Modifying "... | tee -a out.txt" to stream output live, rather than on completion?

我需要在文件上输出命令的输出。假设我的命令是 zip -r zip.zip directory ,我需要 append/write (这些选项中的任何一个都可以)到文件(假设 out.txt )。到目前为止我得到了 zip zip.zip directory | tee -a out.txt,但它似乎不起作用,它只是在命令结束时写入整个输出...我该如何实现?

谢谢 ;)

您是否尝试过选项 command > out.log 2>&1 此日志将所有内容归档而不显示任何内容,所有内容将直接进入文件

背景(即为什么?)

重定向是即时的——当您 运行 somecommand | tee -a out.txtsomecommand 设置其标准输出 直接tee 命令,其文档定义为无缓冲,因此将其输入上可用的任何内容尽快写入其指定的输出接收器。类似地,somecommand >out.txtsomecommand 设置为 out.txt 在 甚至开始之前 字面上写入。

不是立即刷新缓冲输出。

也就是说:标准 C 库,以及大多数其他 tools/languages、buffer 在 stdout 上输出,将小写组合成大写。这通常是可取的,因为减少了对内核的调用次数 space ("context switches"),有利于进行更少数量的更高效、更大的写入。

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


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

如果您使用的是 GNU 平台,并且您的程序按照找到文件描述符的方式保留其文件描述符,而不是尝试显式配置缓冲,您可以使用 stdbuf 命令来配置缓冲:

stdbuf -oL somecommand | tee -a out.txt

将标准输出 (-o) 定义为行缓冲 (L) 当 运行 宁 somecommand.


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

或者,如果您安装了 expect,您可以使用 unbuffer 助手,它包括:

unbuffer somecommand | tee -a out.txt

...这将实际模拟 TTY(如 expect 所做的那样),获得与 somecommand 直接连接到控制台时相同的非缓冲行为。