修改" ... | tee -a out.txt"流输出直播,而不是完成?

时间:2017-03-21 21:05:12

标签: bash output stdout stderr

我需要在文件上输出命令的输出。让我们说我的命令是zip -r zip.zip directory,我需要追加/写(任何这些选项都没问题)到一个文件(让我们说out.txt)。到目前为止我得到了zip zip.zip directory | tee -a out.txt,但它似乎无法工作,它只是在命令结束时写出整个输出......我怎样才能实现这一点?

谢谢;)

2 个答案:

答案 0 :(得分:3)

背景(即为什么?)

立即重定向 - 当您运行somecommand | tee -a out.txt时,somecommand设置为其标准输出直接发送到tee命令,该命令由它的文档是无缓冲的,因此可以尽快将其输入上的任何内容写入指定的输出接收器。同样地,somecommand >out.txtsomecommand设置为out.txt字面,然后才开始

什么立即刷新缓冲输出。

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

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

变通办法(如何? - GNU版本)

如果您使用的是GNU平台,并且您的程序以其找到它们的方式保留其文件描述符而不是尝试明确配置缓冲 ,则可以使用{{1} }命令配置缓冲如下:

stdbuf

在运行stdbuf -oL somecommand | tee -a out.txt 时将stdout(-o)定义为行缓冲(L)。

变通办法(如何? - 期待版本)

或者,如果您安装了somecommand,则可以使用其中包含的expect帮助程序:

unbuffer

...实际上会模拟TTY(如unbuffer somecommand | tee -a out.txt 那样),获得与expect直接连接到控制台时相同的非缓冲行为。

答案 1 :(得分:1)

您是否尝试选择command > out.log 2>&1此日志来记录所有内容而不显示任何内容,所有内容都将直接发送到文件