“less”命令显示输出的时间

我有一个产生大量输出的脚本。 脚本在T点暂停几秒钟。

现在我正在使用less命令来分析脚本的输出。 所以我执行./script | less ./script | less 。 我让它运行足够的时间,以便脚本将完成执行。

现在我按下Pg Down键来查看less命令的输出。 令人惊讶的是,当在输出的T点处滚动时,我注意到几秒钟的停顿。

脚本没有期望任何input,并且在我开始分析输出的时候肯定会完成。

有人可以解释一下,当脚本完成执行时,几秒钟的停顿是如何显示在输出中的?

您的脚本通过管道进行通信的less 。 Pipe是内存中的字节流,连接两个端点:脚本和less程序,前者将输出写入输出,后者从中读取。

由于管道是在内存中,所以如果它们变得任意大,那将是不愉快的。 所以,默认情况下,在任何给定的时刻,管道内部都有数据的限制(写入,但尚未读取)。 默认情况下,它在Linux上是64k。 如果管道已满,并且脚本尝试写入,则写入块。 所以你的脚本实际上并不工作,它在write()调用时停止了

如何克服这一点? 调整默认值是一个不好的选择; 所使用的是在阅读器中分配一个缓冲区,以便它读入缓冲区,释放管道,从而让写程序工作,但只显示给你(或处理)一部分输出。 less了一个这样的缓冲区,并且默认情况下会自动扩展它,但是它并没有填充到后台,只是在读取输入时才填充它。

那么什么解决你的问题是读文件直到结束(就像你通常按G ),然后回到开头(就像你通常会按g )。 问题是你可以像这样通过命令行来指定这些命令:

 ./script | less +Gg 

但是,您应该注意,您将不得不等待整个脚本的输出加载到内存中,因此您将无法一次查看它。 对于这一点来说, less一点是不够复杂 但是,如果这是您真正需要的(在./script仍在计算结束时浏览输出的开头),则可能需要使用临时文件:

  ./script >x & less x ; rm x 

管道在操作系统级别是满的,所以script阻塞,直到消耗一些。

流量控制。 您的脚本正在有效地暂停,而分页更少。

如果你想确保你的命令在交互使用之前就完成了,那么调用less less +G ,它会读到输入的末尾,然后通过输入1G到less来返回到开头。

对于一些背景资料,亚历山大·桑德勒(Alexander Sandler)也有一篇很好的文章,叫做“如何少投入”!

http://www.alexonlinux.com/how-less-processes-its-input

 Can I externally enforce line buffering on the script? Is there an off the shelf pseudo tty utility I could use? 

您可以尝试使用script命令打开行缓冲输出模式。

 script -q /dev/null ./script | less # FreeBSD, Mac OS X script -c "./script" /dev/null | less # Linux 

有关这方面的更多选择,请参阅: 关闭管道中的缓冲 。