如何在 tmux shell 的输出缓冲区内进行搜索?

如何在 tmux shell 的输出缓冲区内进行搜索?

我无法让它工作。我该如何搜索 tmux shell 的缓冲区?

答案1

复制模式搜索

要在历史缓冲区中搜索tmux当前窗口,请按Ctrl-b [进入copy mode

如果您使用的是 emacs 键绑定(默认),请按Ctrl-s然后键入要搜索的字符串并按Enter。按n再次搜索相同的字符串。按Shift-n进行反向搜索。按Escape两次退出copy mode。您可以使用Ctrl-r反向搜索。请注意,由于tmux中的键盘由 控制copy mode,因此无论设置如何, Ctrl-都可以工作(我喜欢将其设置为 以在 Bash 中启用正向搜索)。sstty ixonstty -ixon

如果您使用 vi 键绑定 ( Ctrl- b:set-window-option -g mode-keys vi),请按/然后输入要搜索的字符串并按Enter。按n再次搜索相同的字符串。按Shift-n进行反向搜索,就像在 emacs 模式下一样。按q两次退出copy mode。您可以使用?反向搜索。

查找窗口

如果您想根据窗口中显示的内容切换到窗口(这还包括窗口名称和标题,但不包括历史记录),(从打开多个窗口开始)按Ctrl-b f然后键入要搜索的字符串并按Enter。 如果找到该文本,您将切换到包含该文本的窗口。 如果有多个窗口匹配,您将看到一个可供选择的列表。

答案2

进入复制模式,一键开始搜索

bind-key / copy-mode \; send-key ?

允许您执行以下任务:

 Ctrl + B /

并开始输入搜索词,它将进行向上搜索(最新行优先)。

转储到文件并使用 vim

当事情变得更加复杂时,我只想使用一个合适的编辑器:https://unix.stackexchange.com/questions/26548/write-all-tmux-scrollback-to-a-file

bind-key P 'capture-pane' \; capture-pane -S - \; save-buffer /tmp/tmux \; delete-buffer

现在P将缓冲区转储到文件,然后我只需:

vim /tmp/tmux

我们还可以进一步自动化,自动打开 vim根据 pkfm 的建议

bind-key v 'capture-pane' \; \
  capture-pane -S - \; \
  save-buffer /tmp/tmux \; \
  delete-buffer \; \
  send-keys Escape 'ddivim /tmp/tmux' Enter

这假设你的 shell处于 vi 模式, 以便:

  • Esc 进入正常模式
  • dd清除所有现有命令
  • i进入插入模式
  • 然后我们运行vim /tmp/tmux

在 tmux 3.0 中测试。

答案3

您可以使用 vim 查看/编辑/搜索/保存屏幕日志,在每个 bash 提示符下折叠日志:

tmux capture-pane -pS -1000000 |
  vim +":setl fen fdm=expr fde=getline(v:lnum)=~'^\\\\S\\+\\\\$\\\\s'?'>1':1"  -  

根据您的提示调整正则表达式,在正则表达式中每个反斜杠使用四个反斜杠。

或者将 vim 函数放在 ~/.vimrc 中:

command!           MoshFoldTmuxLog :setl fen fdm=expr
  \   fde=getline(v:lnum)=~'^\\S\\+\\$\\s'?'>1':1 

如果您有大量日志需要搜索,请在 ~/.bashrc 中将日期添加到提示中。例如

PS1='\u@\h:\w:\D{%F-%T}$?:\$ ' # user-host-pwd-date-time-errno 
alias tmux-log='tmux capture-pane -pS -1000000 | vi +MoshFoldTmuxLog -'         

答案4

在搜索 tmux-shell 的输出两次时,你会遇到一个问题:搜索输入框似乎本来就不支持粘贴。我想这就是人们想要一个真正的编辑器或 shell 来完成复杂搜索的原因。我回答了另一个类似的问题。我不确定人们是否愿意考虑朝我所说的方向发展,所以我把链接(原帖标题:TMUX:您能将最新的缓冲区粘贴到搜索字段中吗)供有需要的人参考:)

原帖内容大致如下:

在我的 tmux 3.2a 版本中,copy-mode-vi 下确实有预设的搜索键(#和*)。

bind-key -T copy-mode-vi \# send-key -FX search-backward "#{copy_cursor_word}"
bind-key -T copy-mode-vi * send-key -FX search-forward "#{copy_cursor_word}"

他们直接使用 #{copy_cursor_word} 作为搜索目标,但是如果光标处的文本是连续的整段文本(例如 cmake 变量的值)怎么办?如果你经常进行这种搜索,你就会明白事情没那么简单。我们需要更精确的搜索。

版本 1

bind-key -T copy-mode-vi \\ command-prompt -I "#{copy_cursor_word}" -p "(search up)" "send -X search-backward \"%%%\""

(您可以在自己的 tmux 配置环境中将热键‘\’更改为合适的键值。)

通过这个定义,你可以编辑tmux捕获的内容,并提交你关心的搜索关键词。

发帖者确实提出了一个很好的问题。在他特别提到的纯 tty 环境中,tmux “就是”系统本身,图形系统可能还不存在 :)

我类似的工作场景是:shell 在特定路径下的文件中搜索关键字,然后 tmux 遍历 shell 搜索结果中关键变量的值。tmux 默认的 copy-mode-vi 搜索需要手动输入关键字 —— 在我看来,在纯 tty 环境下是没办法轻松粘贴的(比如说 linux console 模式 —— 没有鼠标,没有 GUI,请不要说前缀 ],我们说的是 copy-mode-vi 模式的搜索输入窗口,而不是退出此模式后的粘贴操作)。因此,采用了一种替代方法 —— 在 shell 搜索结果中选择关键字(版本 1) —— 目前这并不理想,正在改进中。

引入shell脚本后的改进版本:

版本 2

bind-key -T copy-mode-vi \\ run-shell 'tmux command-prompt -I "$(tmux show-buffer)" -p "(search up)" "send -X search-backward \"%%%\""'

但是,这里出现了一个问题:如果复制的内容是 tmux 脚本,它看起来会被执行吗?例如,在 man tmux 中

#{?pane_in_mode,#[fg=white#,bg=red],#[fg=red#,bg=white]}#W .

当你在 copy-mode-vi 下提取此文本时,搜索框不会显示任何内容。如果是纯文本,则没有问题。

那么,版本 1 并不像看起来那么糟糕,对吗?

版本 3

bind-key -T copy-mode-vi y run 'tmux send-keys -X copy-selection "wl-copy" ; \
tmux set -q @buffer_content "$(tmux show-buffer)"'
bind-key : command-prompt -I '#{@buffer_content}' -p '>' \; \
run 'tmux set -u "@buffer_content"'
# Don't duplicate the following \\ with the version 4
bind-key -T copy-mode-vi \\ command-prompt -I '#{@buffer_content}' -p '(search up)' 'send -X search-backward "%%%"'

在上面显示的版本 3 中,wl-copy 用于保持图形环境兼容性,在此场景中不起作用。您可以用 xclip 或其他复制命令替换它。

此版本避免了前两个版本的问题(但仍然没有实现粘贴动作本身)。我将其应用于两种情况:无论是将屏幕内容复制到“copy-mode-vi”模式搜索框中,还是“command-prompt”模式交互窗口的行编辑器中,它都基于相同的逻辑:定义一个额外的@buffer_content来存储最新的缓冲区变量,它将自动以原始形式粘贴到当前正在执行的行编辑器中。您可以正常编辑并提交内容以进行进一步处理。

相关链接在 tmux 复制模式下运行任意命令。它提供的方法和我使用的方法一样。它的优点是自动复制选择,因为它必须在 copy-mode 下工作(通过 send-keys),该实现仍然需要缓存到我机器上的自定义 tmux 变量中,并且应该使用“-I”接口。我的相关版本如下所示:

版本 4

bind-key -T copy-mode-vi \\ send-keys -X copy-selection \; \
run 'tmux set -q @buffer_command "$(tmux show-buffer)"' \; \
command-prompt -I '#{@buffer_command}' -p 'search up>' 'send -X search-backward "%%%"' \; \
run 'tmux set -u "@buffer_command"'

bind-key -T copy-mode-vi : send-keys -X copy-selection \; \
run 'tmux set -q @buffer_command "$(tmux show-buffer)"' \; \
command-prompt -p '>' -I '#{@buffer_command}' \; \
run 'tmux set -u "@buffer_command"'

相关讨论 如何在 tmux shell 的输出缓冲区内进行搜索?

以上代码在 KISS Linux Console 环境下(基本在 Linux 的极简环境下,除了 tmux 本身)可以正常工作,在不同系统下可能会得到不同的结果,如果你有不同的实现或者更好的方案,请回复或者另开主题讨论,谢谢

相关内容