更少滚动到末尾而不阻塞

更少滚动到末尾而不阻塞

我想将一个进程通过管道传输到less,然后发出一个命令来滚动该进程的末尾当前的管道文本。也就是说,如果命令尚未关闭其标准输出,shift+G 会阻塞,因此对于长时间运行的命令,您在完成之前无法看到结尾。

举个例子:

i=0; while true; i=$((i+1)); do echo $i; sleep 0.001; done | less

如果您在开始分页时按 Shift+G less,它不会向下滚动,只会无限期地阻塞。

请注意,我并不担心缓冲- 输出足够频繁,缓冲区不会造成太多延迟。相反,当滚动到当前缓冲区的末尾时,我希望 less 不要挂起(请注意,它挂起更新显示,所以我什至看不到缓冲区的末尾)。

答案1

我处理这个问题的方法是将输出写入文件,然后对文件进行分页。使用你的例子,这将是

i=0; while true; i=$((i+1)); do echo $i; sleep 0.001; done >/tmp/somefile
less /tmp/somefile

缺点是根据生成输出的过程,/tmp/somefile可以增长任意大。

使用文件而不是通过管道进行写入/读取的原因是实用的。该less实用程序有不同的响应,具体取决于它是从管道还是文件中读取。当从文件中读取时,它“知道”文件的末尾并可以立即查找它。如果文件稍后增大,则另一个搜索结束 ( G) 将重新确定终点并重新搜索到该新点。另一方面,寻找管道的末端将会阻塞,直到管道关闭。 (无论管道是缓冲还是无缓冲,这种阻塞效应都适用。)一旦less阻塞,它只会响应Ctrl C,这也会影响生成要查看的输出的进程。不幸的是,这通常会适得其反。

答案2

我不知道这个选项是否ESC-G是新的,但它似乎是您问题的确切解决方案。根据手册:

  ESC-G  Same  as  G,  except  if  no number N is specified and the input is standard input, goes to the last line which is currently buffered.

但不幸的是,我还没有找到如何将其传递给 CLI 上的 less。

相关内容