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

标签 bash output stdout stderr

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

谢谢 ;)

最佳答案

背景(即。为什么?)

重定向是即时的——当您运行 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

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

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

或者,如果您安装了 expect,则可以使用它包含的 unbuffer 助手:
unbuffer somecommand | tee -a out.txt

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

关于bash - 修改 "... | tee -a out.txt"以实时流式传输输出,而不是在完成时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42938106/

相关文章:

linux - 使用 EOF、EOT、EOL 追加多行制表符分隔文本形式的 bash 脚本

linux - Bash 输出流写入文件

console - 抑制控制台输出 - SimpleOpenNI 处理

java - 输出到控制台并登录一个命令? java

bash - 自定义 bash 完成输出 : each suggestion on a new line

bash - 为什么 [ :lower:] return differently in bash depending on the existence of files?

javascript - 在VS 2012中查看typescript输出的js文件

R sink() 消息并输出到同一文件 - 完整性检查

java - 将 System.out.println 或 stdout 数据捕获到 swing 备忘录(大数据)

c - Printf 尝试单独打印变量时打印错误的值,当打印此变量和另一个变量时打印正确的值