Tmux奇技淫巧

Tmux奇技淫巧

在日常的开发工作中,终端是我们最常用的工具之一。在终端中我们可以调用各种解释器,来执行命令,完成我们的工作。然而,对于只使用终端的默认功能的开发者来说,他们可能会错过一些强大的工具和技巧,这些工具和技巧可以大大提高工作效率。

其中一个非常有用的终端工具就是TmuxTmux是一个终端复用器,它允许我们在一个终端窗口中同时运行多个终端会话,并提供了许多有用的功能,如会话管理、窗口分割、窗格布局等。本文将介绍Tmux的基本概念和一些常用的功能,帮助读者更好地利用Tmux提升终端工作效率。

你当然可以使用oh-my-tmux,但是学习基础知识能够帮助你更好的使用这些工具。

1. Why Tmux?

1.1 终端复用

想象这样一个场景,我们通过ssh连接到了远程服务器之后,默认我们会连接到一个交互式解释器中(例如bashzsh)。在同一个交互式解释器中,每次只能运行一条命令,而后等到命令运行结束之后我们才能再运行下一条命令。但很多时候,我们希望能连接到多个解释器,并行执行多个命令。

例如,假设你是一名软件开发者,正在进行一个大型项目的开发工作。为了方便开发,我们需要同时进行多个任务,如运行应用程序、查看日志、执行命令等。

  • 首先,你创建了一个窗口,并将其命名为"代码编辑"。在这个窗口中,你打开了代码编辑器,并开始编写项目的代码。这个窗口用于代码编辑,而为了查看终端的输出,我们还需要创建另外一个窗口
  • 接下来,你创建了另一个窗口,并将其命名为"测试"。在这个窗口中,我们运行测试脚本和查看测试结果。
  • 同时,你还创建了一个名为"服务器"的窗口,用于连接到远程服务器并执行一些部署和管理任务。

在这个场景下,为了完成我们的开发工作,我们打开了多个不同的窗口,而每次切换窗口时都手都需要离开键盘,去点击鼠标。这样一来我们的效率就会被极大地降低。

想象现在有一个软件:

  • 我们可以通过它创建了一个和解释器的会话。在这个会话中,你可以同时进行多个任务,如运行应用程序、查看日志、执行命令等。
  • 其次利用它我们能创建一个窗口,并将其命名为"代码编辑"。在这个窗口中,你打开了代码编辑器,并开始编写项目的代码。而后利用它,我们能将窗口水平分割成两个窗格,一个用于编辑代码,另一个用于查看终端输出。
  • 接下来,你创建了另一个窗口,并将其命名为"测试"。在这个窗口中,你打开了一个终端,用于运行测试脚本和查看测试结果。你可以通过它提供的快捷键在不同的窗口之间快速切换,方便地在编写代码和运行测试之间进行切换。
  • 最后,你还创建了一个名为"服务器"的窗口,用于连接到远程服务器并执行一些部署和管理任务。你可以在这个窗口中使用它提供窗格布局功能,将窗口垂直分割成两个窗格,一个用于连接到服务器,另一个用于执行命令和查看日志。

通过使用这个软件,你可以在同一个终端窗口中同时进行代码编辑、测试和服务器管理等多个任务,而无需打开多个终端窗口。你可以通过它的快捷键快速切换窗口和窗格,轻松地在不同任务之间切换,提高工作效率。

1.2 持久性会话

另外一个场景是,假设你正在远程连接到一台服务器,并需要在该服务器上运行一个需要较长时间才能完成的任务,比如数据处理、模型训练或后台服务。

  • 那么我们连接到服务器并启动任务后,并希望在断开SSH连接后继续运行。这意味着即使你的SSH会话中断或你关闭了终端窗口,任务仍会在后台继续运行。这对于长时间运行的任务非常有用,因为你不必担心任务被中断或终止。
  • 但是SSH默认连接的终端在我们关闭SSH连接后就会终止运行,相应的我们还在运行的任务也会被终止。

因此,在这个场景下,我们希望可以和终端进行持久性会话,这样就关闭SSH链接或者关闭终端窗口后再次打开,你仍然可以恢复到之前的工作状态。

2. 安装Tmux

2.1 包管理器安装

在大多数Linux发行版中,可以使用包管理器进行安装。例如,在Ubuntu上,可以使用以下命令进行安装:

bash 复制代码
sudo apt-get install tmux

2.2 手动编译安装

作为追求技术的程序员,我们当然也可以手动从源码编译安装,毕竟这样更酷。而且包管理器的软件源中的版本可能比较老,因此手动编译安装也是不错的选择。

首先下载并解压源代码

bash 复制代码
mkdir ~/opt/tmux && cd ~/opt/tmux
wget -c https://github.com/tmux/tmux/releases/download/3.3a/tmux-3.3a.tar.gz
tar xzvf tmux-3.3a.tar.gz
mkdir v3.3a && mv tmux* v3.3a

然后编译

bash 复制代码
cd v3.3a/tmux-3.3a
./configure --prefix=/home/jack/opt/tmux/v3.3a/
make -j $(nproc)
make install

编译完成后,就能看到已经有tmux

bash 复制代码
cd ..
tree -L 2 -I tmux-3.3a

最后创建一个软连接,方便未来版本更新。

bash 复制代码
ln -s v3.3a/bin bin
ln -s v3.3a/share share
ll

PS:别忘了添加环境变量。

bash 复制代码
echo 'export PATH="/home/jack/opt/tmux/bin:${PATH}"' >> ~/.zshrc 

3. Tmux基础概念

开始之前,我们先了解下Tmux的基本概念:

  • Tmux采用C/S模型构建,输入Tmux命令就相当于链接到了Tmux服务器,此时默认将新建一个会话,然后会话中默认新建一个窗口,窗口中默认新建一个面板
  • 当前的会话会被保存在Tmux服务器中,即便我们退出了这个会话,下次还可以重新连接到这个回话中,其中运行的命令不会被中断

Tmux的会话、窗口、面板之间的联系如下:

  • 一个Tmux session(会话)可以包含多个window(窗口),窗口默认充满会话界面,因此这些窗口中可以运行相关性不大的任务。
  • 一个window又可以包含多个pane(面板),窗口下的面板,都处于同一界面下,这些面板适合运行相关性高的任务,以便同时观察到它们的运行情况。

4. Tmux的基础使用

4.1 会话操作

新建会话

新建一个tmux session非常简单,语法为tmux new -s session-name,也可以简写为tmux,为了方便管理,建议指定会话名称,如下。

bash 复制代码
tmux # 新建一个无名称的会话
tmux new -s demo # 新建一个名称为demo的会话

注意,Tmux默认是不允许session之间嵌套的,因此这个命令需要在session外使用

进入会话后,终端的下面就会显示绿色的状态栏,其中描述了诸多信息。

断开当前会话

会话中操作了一段时间,我希望断开会话同时下次还能接着用,怎么做?此时可以使用detach命令。

bash 复制代码
tmux detach # 断开当前会话,会话在后台运行

也许你觉得这个太麻烦了,是的,tmux的会话中,我们可以使用tmux快捷键了。使用快捷键组合Ctrl+b + d,三次按键就可以断开当前会话。

进入之前的会话

断开会话后,想要接着上次留下的现场继续工作,就要使用到tmux的attach命令了,语法为tmux attach-session -t session-name,可简写为tmux a -t session-nametmux a。通常我们使用如下两种方式之一即可:

bash 复制代码
tmux a # 默认进入第一个会话
tmux a -t demo # 进入到名称为demo的会话
关闭会话

会话的使命完成后,一定是要关闭的。我们可以使用tmux的kill命令,kill命令有kill-panekill-serverkill-sessionkill-window共四种,其中kill-session的语法为tmux kill-session -t session-name。如下:

bash 复制代码
tmux kill-session -t demo # 关闭demo会话
tmux kill-server # 关闭服务器,所有的会话都将关闭
查看所有的会话

管理会话的第一步就是要查看所有的会话,我们可以使用如下命令:

bash 复制代码
tmux list-session # 查看所有会话
tmux ls # 查看所有会话,提倡使用简写形式

如果刚好处于会话中怎么办?别担心,我们可以使用对应的tmux快捷键Ctrl+b + s,此时tmux将打开一个会话列表,按上下键(⬆︎⬇︎)或者鼠标滚轮,可选中目标会话,按左右键可收起或展开会话的窗口,选中目标会话或窗口后,按回车键即可完成切换。

重命名会话

tmux rename-session命令用于重命名会话。

bash 复制代码
tmux rename-session -t 0 <new-name>

上面命令将0号会话重命名。

但事实上一般更常用的是重命名当前会话,所以直接使用快捷键Ctrl+b + $

4.2 窗口操作

新建窗口

tmux new-window命令用来创建新窗口。

bash 复制代码
tmux new-window
# 新建一个指定名称的窗口
tmux new-window -n <window-name>
切换窗口

tmux select-window命令用来切换窗口。

bash 复制代码
# 切换到指定编号的窗口
tmux select-window -t <window-number>

# 切换到指定名称的窗口
tmux select-window -t <window-name>
重命名窗口

tmux rename-window命令用于为当前窗口起名(或重命名)。

bash 复制代码
tmux rename-window <new-name>
窗口快捷键

下面是一些窗口操作的快捷键。

  • Ctrl+b c:创建一个新窗口,状态栏会显示多个窗口的信息。
  • Ctrl+b p:切换到上一个窗口(按照状态栏上的顺序)。
  • Ctrl+b n:切换到下一个窗口。
  • Ctrl+b <number>:切换到指定编号的窗口,其中的<number>是状态栏上的窗口编号。
  • Ctrl+b w:从列表中选择窗口。
  • Ctrl+b ,:窗口重命名。

更多的命令就不介绍了,因为相比于使用命令来说,更常用的是直接使用快捷键。

5. Tmux快捷键

关于快捷键,首先要认识到的是:tmux的所有快捷键,都包含同一个前缀,默认为Ctrl+b,输入完前缀过后,控制台激活,命令按键才能生效。前面tmux会话相关的操作中,我们共用到了两个快捷键Ctrl+b + dCtrl+b + s,但这仅仅是冰山一角,欲窥tmux庞大的快捷键体系,请看下表。

5.1 Tmux系统指令

前缀 指令 描述
Ctrl+b ? 显示快捷键帮助文档
Ctrl+b d 断开当前会话
Ctrl+b D 选择要断开的会话
Ctrl+b Ctrl+z 挂起当前会话
Ctrl+b r 强制重载当前会话
Ctrl+b s 显示会话列表用于选择并切换
Ctrl+b : 进入命令行模式,此时可直接输入ls等命令
Ctrl+b [ 进入复制模式,按q退出
Ctrl+b ] 粘贴复制模式中复制的文本
Ctrl+b ~ 列出提示信息缓存

5.2 窗口(window)指令。

前缀 指令 描述
Ctrl+b c 新建窗口
Ctrl+b & 关闭当前窗口(关闭前需输入y or n确认)
Ctrl+b 0~9 切换到指定窗口
Ctrl+b p 切换到上一窗口
Ctrl+b n 切换到下一窗口
Ctrl+b w 打开窗口列表,用于且切换窗口
Ctrl+b , 重命名当前窗口
Ctrl+b . 修改当前窗口编号(适用于窗口重新排序)
Ctrl+b f 快速定位到窗口(输入关键字匹配窗口名称)

5.3 面板(pane)指令。

前缀 指令 描述
Ctrl+b " 当前面板上下一分为二,下侧新建面板
Ctrl+b % 当前面板左右一分为二,右侧新建面板
Ctrl+b x 关闭当前面板(关闭前需输入y or n确认)
Ctrl+b z 最大化当前面板,再重复一次按键后恢复正常(v1.8版本新增)
Ctrl+b ! 将当前面板移动到新的窗口打开(原窗口中存在两个及以上面板有效)
Ctrl+b ; 切换到最后一次使用的面板
Ctrl+b q 显示面板编号,在编号消失前输入对应的数字可切换到相应的面板
Ctrl+b { 向前置换当前面板
Ctrl+b } 向后置换当前面板
Ctrl+b Ctrl+o 顺时针旋转当前窗口中的所有面板
Ctrl+b 方向键 移动光标切换面板
Ctrl+b o 选择下一面板
Ctrl+b 空格键 在自带的面板布局中循环切换
Ctrl+b Alt+方向键 以5个单元格为单位调整当前面板边缘
Ctrl+b Ctrl+方向键 以1个单元格为单位调整当前面板边缘(Mac下被系统快捷键覆盖)
Ctrl+b t 显示时钟

tmux的丝滑分屏功能正是得益于以上系统、窗口、面板的快捷指令,只要你愿意,你就可以解除任意的快捷指令,然后绑上你喜欢的指令,当然这就涉及到tmux的配置了。

6. Tmux的配置文件

类似于.bashrc.zshrc,tmux提供了类似的配置文件。通过编写配置文件就可以实现更加强大的功能。

tmux的用户级配置文件为~/.tmux.conf(没有的话就创建一个),修改快捷指令,只需要增加如下三行即可。如果你的主目录下还没有 .tmux.conf 文件,你可以使用文本编辑器创建一个新的文件并将其保存为 .tmux.conf

配置文件使用简单的语法来定义设置和命令。每个设置或命令占据一行,可以使用 # 符号进行注释。

6.0 Tmux配置文件的指令

在 Tmux 配置文件中,可以使用以下几类命令:

  1. set 命令:用于设置各种选项和参数。可以使用 set -g 命令设置全局选项,使用 set -u 命令取消选项设置,使用 set -g option value 命令设置具体的选项和对应的值。例如,set -g prefix C-a 将前缀键设置为 Ctrl+a

  2. bind-key 命令:用于创建键绑定,将特定的键映射到指定的命令。可以使用 bind-key -n 命令创建无前缀键绑定,使用 bind-key 命令创建带前缀键绑定。例如,bind-key -n C-a new-windowCtrl+a 绑定到新建窗口的命令。

  3. unbind-key 命令:用于解除键绑定,取消特定键的映射。可以使用 unbind-key -n 命令解除无前缀键绑定,使用 unbind-key 命令解除带前缀键绑定。例如,unbind-key -n C-a 将取消 Ctrl+a 的绑定。

  4. source-file 命令:用于重新加载配置文件,使新的设置生效。可以使用 source-file ~/.tmux.conf 命令重新加载主配置文件。这在你编辑完配置文件后需要使更改生效时非常有用。

  5. alias 命令:用于创建命令别名。可以使用 alias -g 命令创建全局别名,使用 alias 命令创建局部别名。例如,alias -g L "list-sessions"L 定义为 list-sessions 命令的别名。

这些命令可以在 Tmux 配置文件中使用,用于自定义和配置 Tmux 的行为、键绑定、外观和其他选项。通过合理使用这些命令,你可以根据自己的需求创建一个适合自己的 Tmux 环境。

下面就介绍一些常用的配置。

6.1 修改指令前缀

相信只要你用过几次tmux,就会发现Ctrl+b指令前缀,着实不太方便。这两个键相距太远,按键成本太高了。因此我们首先需要将它更换为距离更近的Ctrl+a组合键,或者不常用的 ` 键。

ini 复制代码
set -g prefix C-a # 将快捷键前缀设置为Ctrl+a
unbind C-b # C-b即Ctrl+b键,unbind意味着解除绑定
bind C-a send-prefix # 绑定Ctrl+a为新的指令前缀

# 从tmux v1.6版起,支持设置第二个指令前缀
set-option -g prefix2 ` # 设置一个不常用的`键作为指令前缀,按键更快些

修改的~/.tmux.conf配置文件有如下两种方式可以令其生效:

  • restart tmux。
  • 在tmux窗口中,先按下Ctrl+b指令前缀,然后按下系统指令:,进入到命令模式后输入source-file ~/.tmux.conf,回车后生效。

6.2 加载配置文件快捷键

既然快捷键如此方便,更为优雅的做法是新增一个加载配置文件的快捷键 ,这样就可以随时随地load新的配置了,如下所示。

bash 复制代码
# 绑定快捷键为r
bind r source-file ~/.tmux.conf \; display-message "Config reloaded.."

请特别注意,在已经创建的窗口中,即使加载了新的配置,旧的配置依然有效(只要你新加的功能没有覆盖旧的配置,因此如果你第一次绑定快捷指令为x键,然后又改为绑定y键,那么xy都将有效),新建会话不受此影响,将直接采用新的配置。

既然我们已经迈出配置化的第一步,那么接下来我们可以做得更多。

6.3 新增面板

tmux中,使用最多的功能之一就是新增一个面板。水平方向新增面板的指令是 prefix + " ,垂直方向是 prefix + %"%需要两个键同时按下才能完成,加上指令前缀至少需要3~4次按键才能组成一个完整的指令,同时这个两个键也不够醒目和方便,因此我们可以绑定两个更常用的指令 -|,如下所示:

bash 复制代码
unbind '"'
bind - splitw -v -c '#{pane_current_path}' # 垂直方向新增面板,默认进入当前目录
unbind %
bind | splitw -h -c '#{pane_current_path}' # 水平方向新增面板,默认进入当前目录

6.4 开启鼠标支持

默认情况下,tmux的多窗口之间的切换以及面板大小调整,需要输入指令才能完成,这一过程,涉及到的指令较多,而且操作麻烦,特别是面板大小调整,指令难以一步到位,这个时候开启鼠标支持就完美了。

对于tmux v2.1(2015.10.28)之前的版本,需加入如下配置:

bash 复制代码
setw -g mode-mouse on # 支持鼠标选取文本等
setw -g mouse-resize-pane on # 支持鼠标拖动调整面板的大小(通过拖动面板间的分割线)
setw -g mouse-select-pane on # 支持鼠标选中并切换面板
setw -g mouse-select-window on # 支持鼠标选中并切换窗口(通过点击状态栏窗口名称)

有的地方可能会出现set-window-option的写法,setw就是它的别名。

对于tmux v2.1及以上的版本,仅需加入如下配置:

bash 复制代码
set-option -g mouse on # 等同于以上4个指令的效果

需要注意的是,开启鼠标支持后,iTem2默认的鼠标选中即复制功能需要同时按下 Alt 键,才会生效。

6.5 快速面板切换

鼠标支持确实能带来很大的便捷性,特别是对于习惯了鼠标操作的tmux新手,但对于键盘爱好者而言,这不是什么好消息,对他们而言,双手不离键盘是基本素质。

虽然指令前缀加方向键可以切换面板,但方向键太远,不够快,不够Geek。没关系,我们可以将面板切换升级为熟悉的hjkl键位。

bash 复制代码
# 绑定hjkl键为面板切换的上下左右键
bind -r k select-pane -U # 绑定k为↑
bind -r j select-pane -D # 绑定j为↓
bind -r h select-pane -L # 绑定h为←
bind -r l select-pane -R # 绑定l为→

-r表示可重复按键,大概500ms之内,重复的hjkl按键都将有效,完美支持了快速切换的Geek需求。

除了上下左右外, 还有几个快捷指令可以设置。

bash 复制代码
bind -r e lastp # 选择最后一个面板
bind -r ^e last # 选择最后一个窗口

bind -r ^u swapp -U # 与前一个面板交换位置
bind -r ^d swapp -D # 与后一个面板交换位置

6.6 面板大小调整

习惯了全键盘操作后,命令的便捷性不言而喻。既然面板切换的指令都可以升级,面板大小调整的指令自然也不能落后。如下配置就可以升级你的操作:

bash 复制代码
# 绑定Ctrl+hjkl键为面板上下左右调整边缘的快捷指令
bind -r ^k resizep -U 10 # 绑定Ctrl+k为往↑调整面板边缘10个单元格
bind -r ^j resizep -D 10 # 绑定Ctrl+j为往↓调整面板边缘10个单元格
bind -r ^h resizep -L 10 # 绑定Ctrl+h为往←调整面板边缘10个单元格
bind -r ^l resizep -R 10 # 绑定Ctrl+l为往→调整面板边缘10个单元格

以上,resizepresize-pane的别名。

6.7 面板最大化

当窗口中面板的数量逐渐增多时,每个面板的空间就会逐渐减少。为了保证有足够的空间显示内容,tmux从v1.8版本起,提供了面板的最大化功能,输入tmux-prefix+z,就可以最大化当前面板至窗口大小,只要再重复输入一次,便恢复正常。

6.8 窗口变为面板

面板可以轻松地最大化为一个新的窗口。那么反过来,窗口是不是可以最小化为一个面板呢?

试想这样一个场景:当你打开多个窗口后,然后想将其中几个窗口合并到当前窗口中,以便对比观察输出。

实际上,你的要求就是将其它窗口变成面板,然后合并到当前窗口中。对于这种操作,我们可以在当前窗口,按下prefix + :,打开命令行,然后输入如下命令:

bash 复制代码
join-pane -s window01 # 合并名称为window01的窗口的默认(第一个)面板到当前窗口中
join-pane -s window01.1 # .1显式指定了第一个面板,.2就是第二个面板(我本地将面板编号起始值设置为1,默认是0)

每次执行join-pane命令都会合并一个面板,并且指定的窗口会减少一个面板,直到面板数量为0,窗口关闭。

除了在当前会话中操作外,join-pane命令甚至可以从其它指定会话中合并面板,格式为join-pane -s [session_name]:[window].[pane],如join-pane -s 2:1.1 即合并第二个会话的第一个窗口的第一个面板到当前窗口,当目标会话的窗口和面板数量为0时,会话便会关闭。

注:上一节中的swap-pane命令与join-pane语法基本一致。

6.9 其他配置

bash 复制代码
bind m command-prompt "splitw -h 'exec man %%'"   # 绑定m键为在新的panel打开man
# 绑定P键为开启日志功能,如下,面板的输出日志将存储到桌面
bind P pipe-pane -o "cat >>~/Desktop/#W.log" \; display "Toggled logging to ~/Desktop/#W.log"

6.10 恢复用户空间

tmux会话中,Mac的部分命令如 osascriptopenpbcopypbpaste等可能会失效(失效命令未列全)。

部分bug列表如下:

对此,我们可以通过安装reattach-to-user-namespace包装程序来解决这个问题。

bash 复制代码
brew install reattach-to-user-namespace

~/.tmux.conf中添加配置:

bash 复制代码
set -g default-command "reattach-to-user-namespace -l $SHELL"

这样你的交互式shell最终能够重新连接到用户级的命名空间。由于连接状态能够被子进程继承,故以上配置保证了所有从 shell 启动的命令能够被正确地连接。

有些时候,我们可能会在不同的操作系统中共享配置文件,如果你的tmux版本大于1.9,我们还可以使用if-shell来判断是否Mac系统,然后再指定default-command

bash 复制代码
if-shell 'test "$(uname -s)" = Darwin' 'set-option -g default-command "exec reattach-to-user-namespace -l $SHELL"'

对于tmux v1.8及更早的版本,可以使用如下包装后的配置:

bash 复制代码
set-option -g default-command 'command -v reattach-to-user-namespace >/dev/null && exec reattach-to-user-namespace -l "$SHELL" || exec "$SHELL"'

以上,$SHELL对应于你的默认Shell,通常是/usr/bin/bash/usr/local/bin/zsh

7. 复制模式

tmux中操作文本,自然离不开复制模式,通常使用复制模式的步骤如下:

  1. 输入 ``+[` 进入复制模式
  2. 按下 空格键 开始复制,移动光标选择复制区域
  3. 按下 回车键 复制选中文本并退出复制模式
  4. 按下 ``+]` 粘贴文本

查看复制模式默认的快捷键风格:

bash 复制代码
tmux show-window-options -g mode-keys # mode-keys emacs

默认情况下,快捷键为emacs风格。

为了让复制模式更加方便,我们可以将快捷键设置为熟悉的vi风格,如下:

bash 复制代码
setw -g mode-keys vi # 开启vi风格后,支持vi的C-d、C-u、hjkl等快捷键

7.1 自定义复制和选择快捷键

除了快捷键外,复制模式的启用、选择、复制、粘贴等按键也可以向vi风格靠拢。

bash 复制代码
bind Escape copy-mode # 绑定esc键为进入复制模式
bind -t vi-copy v begin-selection # 绑定v键为开始选择文本
bind -t vi-copy y copy-selection # 绑定y键为复制选中文本
bind p pasteb # 绑定p键为粘贴文本(p键默认用于进入上一个窗口,不建议覆盖)

以上,绑定 vy两键的设置只在tmux v2.4版本以下才有效,对于v2.4及以上的版本,绑定快捷键需要使用 -T 选项,发送指令需要使用 -X 选项,请参考如下设置:

bash 复制代码
bind -T copy-mode-vi v send-keys -X begin-selection
bind -T copy-mode-vi y send-keys -X copy-selection-and-cancel

7.2 Buffer缓存

tmux复制操作的内容默认会存进buffer里,buffer是一个粘贴缓存区,新的缓存总是位于栈顶,它的操作命令如下:

bash 复制代码
tmux list-buffers # 展示所有的 buffers
tmux show-buffer [-b buffer-name] # 显示指定的 buffer 内容
tmux choose-buffer # 进入 buffer 选择页面(支持jk上下移动选择,回车选中并粘贴 buffer 内容到面板上)
tmux set-buffer # 设置buffer内容
tmux load-buffer [-b buffer-name] file-path # 从文件中加载文本到buffer缓存
tmux save-buffer [-a] [-b buffer-name] path # 保存tmux的buffer缓存到本地
tmux paste-buffer # 粘贴buffer内容到会话中
tmux delete-buffer [-b buffer-name] # 删除指定名称的buffer

以上buffer操作在不指定buffer-name时,默认处理是栈顶的buffer缓存。

在tmux会话的命令行输入时,可以省略上述tmux前缀,其中list-buffers的操作如下所示:

choose-buffer的操作如下所示:

默认情况下,buffers内容是独立于系统粘贴板的,它存在于tmux进程中,且可以在会话间共享。

7.3 使用系统粘贴板

存在于tmux进程中的buffer缓存,虽然可以在会话间共享,但不能直接与系统粘贴板共享,不免有些遗憾。幸运的是,现在我们有成熟的方案来实现这个功能。

A. 在Linux上使用粘贴板

通常,Linux中可以使用xclip工具来接入系统粘贴板。

首先,需要安装xclip

bash 复制代码
sudo apt-get install xclip

然后,.tmux.conf的配置如下。

bash 复制代码
# buffer缓存复制到Linux系统粘贴板
bind C-c run " tmux save-buffer - | xclip -i -sel clipboard"
# Linux系统粘贴板内容复制到会话
bind C-v run " tmux set-buffer \"$(xclip -o -sel clipboard)\"; tmux paste-buffer"

按下prefix + Ctrl + c 键,buffer缓存的内容将通过xlip程序复制到粘贴板,按下prefix + Ctrl + v键,tmux将通过xclip访问粘贴板,然后由set-buffer命令设置给buffer缓存,最后由paste-buffer粘贴到tmux会话中。

B. 在Mac上使用粘贴板

我们都知道,Mac自带 pbcopypbpaste命令,分别用于复制和粘贴,但在tmux命令中它们却不能正常运行。这里我将详细介绍下原因:

Mac的粘贴板服务是在引导命名空间注册的。命名空间存在层次之分,更高级别的命名空间拥有访问低级别命名空间(如root引导命名空间)的权限,反之却不行。流程创建的属于Mac登录会话的一部分,它会被自动包含在用户级的引导命名空间中,因此只有用户级的命名空间才能访问粘贴板服务。tmux使用守护进程(3)库函数创建其服务器进程,在Mac OS X 10.5中,苹果改变了守护进程(3)的策略,将生成的过程从最初的引导命名空间移到了根引导命名空间。而根引导命名空间访问权限较低,这意味着tmux服务器,和它的子进程,一同失去了原引导命名空间的访问权限(即无权限访问粘贴板服务)。

如此,我们可以使用一个小小的包装程序来重新连接到合适的命名空间,然后执行访问用户级命名空间的粘贴板服务,这个包装程序就是reattach-to-user-namespace

那么,Mac下.tmux.conf的配置如下:

bash 复制代码
# buffer缓存复制到Mac系统粘贴板
bind C-c run "tmux save-buffer - | reattach-to-user-namespace pbcopy"
# Mac系统粘贴板内容复制到会话
bind C-v run "reattach-to-user-namespace pbpaste | tmux load-buffer - \; paste-buffer -d"

reattach-to-user-namespace 作为包装程序来访问Mac粘贴板,按下prefix + Ctrl + c 键,buffer缓存的内容将复制到粘贴板,按下prefix + Ctrl + v键,粘贴板的内容将通过 load-buffer 加载,然后由 paste-buffer 粘贴到tmux会话中。

为了在复制模式中使用Mac系统的粘贴板,可做如下配置:

bash 复制代码
# 绑定y键为复制选中文本到Mac系统粘贴板
bind-key -T copy-mode-vi 'y' send-keys -X copy-pipe-and-cancel 'reattach-to-user-namespace pbcopy'
# 鼠标拖动选中文本,并复制到Mac系统粘贴板
bind-key -T copy-mode-vi MouseDragEnd1Pane send -X copy-pipe-and-cancel "pbcopy"

完成以上配置后记得重启tmux服务器。至此,复制模式中,按y键将保存选中的文本到Mac系统粘贴板,随后按Command + v键便可粘贴。

相关推荐
码农小白3 分钟前
linux驱动:(22)中断节点和中断函数
linux·运维·服务器
4647的码农历程4 分钟前
Linux网络编程 -- 网络基础
linux·运维·网络
醉颜凉29 分钟前
银河麒麟桌面操作系统V10 SP1:取消安装应用的安全授权认证
运维·安全·操作系统·国产化·麒麟·kylin os·安全授权认证
C++忠实粉丝1 小时前
Linux环境基础开发工具使用(2)
linux·运维·服务器
康熙38bdc2 小时前
Linux 环境变量
linux·运维·服务器
存储服务专家StorageExpert2 小时前
DELL SC compellent存储的四种访问方式
运维·服务器·存储维护·emc存储
hakesashou3 小时前
python如何比较字符串
linux·开发语言·python
Ljubim.te3 小时前
Linux基于CentOS学习【进程状态】【进程优先级】【调度与切换】【进程挂起】【进程饥饿】
linux·学习·centos
cooldream20093 小时前
Linux性能调优技巧
linux
大G哥3 小时前
记一次K8S 环境应用nginx stable-alpine 解析内部域名失败排查思路
运维·nginx·云原生·容器·kubernetes