终止 less(1) 中的文本搜索并继续通过 Unix 管道读取

终止 less(1) 中的文本搜索并继续通过 Unix 管道读取
gunzip < 100terabytes.txt.gz | less

less(1)根据需要读取尽可能多的行以填满屏幕,然后停止read(2)。结果,当管道变满时,gunzip(1)就会被堵塞。write(2)

当您向下滚动时,会一次又一次地less(1)发出问题read(2),并且当管道被消耗时,gunzip(1)允许发出write(2)。您可以在这里来回完全灵活(假设gunzip < 100terabytes.txt.gz未完成。)

到目前为止一切都很好。

less(1)您可以使用开始文本搜索/。但是,当在 中找不到搜索字符串时100terabytes.txtless(1)基本上变得无响应。您可以使用 终止搜索Ctrl-Cgunzip(1)它似乎关闭了和之间的管道less(1)。我不喜欢这个。我想gunzip(1)在放弃文本搜索后手动向下滚动以消耗更多行。这可能吗?

我是不是寻求建议,例如gunzip < 100terabytes.txt.gz | grep pattern | less

更新

你可以尝试一下od -v /dev/zero | less

答案1

当你按下 时Ctrl+C,这就是整个外壳工作(进程组)接收 SIGINT,less拦截它以中止搜索,但gunzip会终止。为了避免这种情况,你可以这样做:

(trap '' INT; gunzip < file.gz) | less

这样就忽略了 SIGINT,但请注意,此后gunzip您将无法再中断。gunzip

对于gunzip,这可能没问题,因为您需要做的就是退出,下次它写入某些内容时就会因 SIGPIPE 而死亡,但对于只是挂起而不输出某些内容的应用程序,这将是一个更大的问题(您仍然less会不过gunzip可以用于Ctrl+ZSIGTSTP 或Ctrl+\SIGQUIT)。

另请注意,某些命令例如pvping安装它们自己的 SIGINT 处理程序,这将恢复我们的trap '' INT.

您可以创建一个函数来保存输入,例如:

iless() {
  (trap '' INT; "$@") | less
}

iless gunzip < file.gz

或者:

noint() (trap '' INT; "$@")

noint gunzip < file.gz | less

但请注意,对于:

gunzip < file.gz | grep foo | less

你需要写它:

noint gunzip < file.gz | notint grep foo | less

或者:

noint eval 'gunzip < file.gz | grep foo' | less

或者:

iless eval 'gunzip < file.gz | grep foo'

另一种方法是使用进程替换:

less -f <(gunzip < file.gz | grep foo)

或(尽管不在 中zsh):

less < <(gunzip < file.gz | grep foo)

在这些情况下,shell 不会在前台进程组中的进程替换中包含命令(除了 for 的第二种情况zsh)。它们的进程组与 shell 的进程组相同。这意味着当您按 时他们不会收到 SIGINT Ctrl+C

请注意,这些进程不会受到Ctrl+ZCtrl+\的影响。

zshksh93和中进行了测试bash

答案2

不是确切的答案,但它可能会解决您的问题。从man less

       ESC-F  Like  F,  but  as soon as a line is found which matches the last
              search pattern, the terminal bell is rung and forward  scrolling
              stops.

这可以被中断,^C但我不知道它是否会破坏管道,因为我无法重现你的问题(我认为需要一个非常大的输入文件来测试这一点)。我认为它不会破坏管道,因为通常您可以在不断增长的文件上重复执行F此操作,并且仍然有效(您仍然看到文件不断增长)。^CF

问题是:less如果没有找到模式,如何输入“最后搜索的模式”而不冻结?也许^K选项/会有所帮助:

          ^K     Highlight any text which matches the pattern on the  cur-
                 rent screen, but don't move to the first match (KEEP cur-
                 rent position).

编辑:或者更简单地说,用于?“设置”此“最后搜索模式”。

相关内容