加载中...

Tmux使用教程

linux,mac zsh 安装tmux 常用配置

一. tmux 简介

指令全

https://gist.github.com/ryerh/14b7c24dfd623ef8edc7

tmux是一款优秀的终端复用软件,它比Screen更加强大,至于如何强大,网上有大量的文章讨论了这点,本文不再重复。tmux之所以受人们喜爱,主要得益于以下三处功能:

  • 丝滑分屏(split),虽然iTem2也提供了横向和竖向分屏功能,但这种分屏功能非常拙劣,完全等同于屏幕新开一个窗口,新开的pane不会自动进入到当前目录,也没有记住当前登录状态。这意味着如果我ssh进入到远程服务器时,iTem2新开的pane中,我依然要重新走一遍ssh登录的老路(omg)。tmux就不会这样,tmux窗口中,新开的pane,默认进入到之前的路径,如果是ssh连接,登录状态也依旧保持着,如此一来,我就可以随意的增删pane,这种灵活性,好处不言而喻。
  • 保护现场(attach),即使命令行的工作只进行到一半,关闭终端后还可以重新进入到操作现场,继续工作。对于ssh远程连接而言,即使网络不稳定也没有关系,掉线后重新连接,可以直奔现场,之前运行中的任务,依旧在跑,就好像从来没有离开过一样;特别是在远程服务器上运行耗时的任务,tmux可以帮你一直保持住会话。如此一来,你就可以随时随地放心地进行移动办公,只要你附近的计算机装有tmux(没有你也可以花几分钟装一个),你就能继续刚才的工作。
  • 会话共享(适用于结对编程或远程教学),将 tmux 会话的地址分享给他人,这样他们就可以通过 SSH 接入该会话。如果你要给同事演示远程服务器的操作,他不必直勾勾地盯着你的屏幕,借助tmux,他完全可以进入到你的会话,然后静静地看着他桌面上你风骚的键盘走位,只要他愿意,甚至还可以录个屏。

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

tmux采用C/S模型构建,输入tmux命令就相当于开启了一个服务器,此时默认将新建一个会话,然后会话中默认新建一个窗口,窗口中默认新建一个面板。会话、窗口、面板之间的联系如下:

一个tmux session(会话)可以包含多个window(窗口),窗口默认充满会话界面,因此这些窗口中可以运行相关性不大的任务。

一个window又可以包含多个pane(面板),窗口下的面板,都处于同一界面下,这些面板适合运行相关性高的任务,以便同时观察到它们的运行情况。

server服务器。输入tmux命令时就开启了一个服务器。
session会话。一个服务器可以包含多个会话。
window窗口。一个会话可以包含多个窗口。
pane面板。一个窗口可以包含多个面板。

img

二. tmux 安装和配置

1 新建会话

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

1
2
tmux # 新建一个无名称的会话
tmux new -s demo # 新建一个名称为demo的会话
Copied!

2 断开当前会话

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

1
tmux detach # 断开当前会话,会话在后台运行
Copied!

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

3 进入之前的会话

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

1
2
tmux a # 默认进入第一个会话
tmux a -t demo # 进入到名称为demo的会话
Copied!

4 关闭会话

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

1
2
tmux kill-session -t demo # 关闭demo会话
tmux kill-server # 关闭服务器,所有的会话都将关闭
Copied!

在会话内退出并删除session

1
2
Ctrl+b 
:kill-session
Copied!

5 查看会话

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

1
2
tmux list-session # 查看所有会话
tmux ls # 查看所有会话,提倡使用简写形式
Copied!

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

img

6 tmux快捷命令

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

Ctrl+b + s 进入信息列表,然后选中某个session或者window或者pane,然后按 x ,都可以删除

表一:系统指令。

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

表二:窗口(window)指令。

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

表三:面板(pane)指令。

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

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

7 tmux滚屏

使用快捷键进入 copy-mode 模式,就可以利用方向键上下移动光标查看了,但是如果历史信息太多,一行一行未免太不爽了,该如何操作呢?

1.先打开配置文件:

1
vim ~/.tmux.conf
Copied!

2.将下面设置输入:

1
setw -g mode-keys vi
Copied!

3.重新载入配置文件:

1
tmux source-file ~/.tmux.conf
Copied!

4.使用快捷键进入 copy-mode 模式,然后就可以像 vi 中一样操作了。

比如:Ctrl-u 向上滚半屏, Ctrl-d 向下滚半屏。

根据某关键字搜索

使用快捷键进入 copy-mode 模式,然后按 / ,就可以输入关键字了,回车查找。

四. 恢复用户空间

1 复制模式

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

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

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

1
tmux show-window-options -g mode-keys # mode-keys emacs
Copied!

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

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

1
setw -g mode-keys vi # 开启vi风格后,支持vi的C-d、C-u、hjkl等快捷键
Copied!

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

1
2
3
4
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键默认用于进入上一个窗口,不建议覆盖)
Copied!

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

1
2
bind -T copy-mode-vi v send-keys -X begin-selection
bind -T copy-mode-vi y send-keys -X copy-selection-and-cancel
Copied!

2 buffer缓存

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

1
2
3
4
5
6
7
8
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
Copied!

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

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

img ·

choose-buffer的操作如下所示:

choose-buffer

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

3 使用系统粘贴板

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

在Linux上使用粘贴板

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

首先,需要安装xclip

1
sudo apt-get install xclip
Copied!

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

1
2
3
4
# 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"
Copied!

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

在Mac上使用粘贴板

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

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

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

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

1
2
3
4
# 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"
Copied!

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

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

1
2
3
4
# 绑定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"
Copied!

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

六.保存Tmux会话

1 结对编程

tmux多会话连接实时同步的功能,使得结对编程成为了可能,这也是开发者最喜欢的功能之一。现在就差一步了,就是借助tmate把tmux会话分享出去。

tmate是tmux的管理工具,它可以轻松的创建tmux会话,并且自动生成ssh链接。

安装tmate

1
brew install tmate
Copied!

使用tmate新建一个tmux会话

1
tmate
Copied!

此时屏幕下方会显示ssh url,如下所示:

img

查看tmate生成的ssh链接

1
tmate show-messages
Copied!

生成的ssh url如下所示,其中一个为只读,另一个可编辑。

ssh url

2 共享账号&组会话

使用tmate远程共享tmux会话,受制于多方的网络质量,必然会存在些许延迟。如果共享会话的多方拥有同一个远程服务器的账号,那么我们可以使用组会话解决这个问题。

先在远程服务器上新建一个公共会话,命名为groupSession

1
tmux new -s groupSession
Copied!

其他用户不去直接连接这个会话,而是通过创建一个新的会话来加入上面的公共会话groupSession

1
tmux new -t groupSession -s otherSession
Copied!

此时两个用户都可以在同一个会话里操作,就会好像第二个用户连接到了groupSession的会话一样。此时两个用户都可以创建新建的窗口,新窗口的内容依然会实时同步,但是其中一个用户切换到其它窗口,对另外一个用户没有任何影响,因此在这个共享的组会话中,用户各自的操作可以通过新建窗口来执行。即使第二个用户关闭otherSession会话,共享会话groupSession依然存在。

组会话在共享的同时,又保留了相对的独立,非常适合结对编程场景,它是结对编程最简单的方式,如果账号不能共享,我们就要使用下面的方案了。

3 独立账号&Socket共享会话

开始之前我们需要确保用户对远程服务器上同一个目录拥有相同的读写权限,假设这个目录为/var/tmux/

使用new-session(简写new)创建会话时,使用的是默认的socket位置,默认socket无法操作,所以我们需要创建一个指定socket文件的会话。

1
tmux -S /var/tmux/sharefile
Copied!

另一个用户进入时,需要指定socket文件加入会话。

1
tmux -S /var/tmux/sharefile attach
Copied!

这样,两个不同的用户就可以共享同一个会话了。

通常情况下,不同的用户使用不同的配置文件来创建会话,但是,使用指定socket文件创建的tmux会话,会话加载的是第一个创建会话的用户的~/.tmux.conf配置文件,随后加入会话的其他用户,依然使用同一份配置文件。

八.Tmux优化

tmux作为终端复用软件,支持纯命令行操作也是其一大亮点。你既可以启用可视化界面创建会话,也可以运行脚本生成会话,对于tmux依赖者而言,编写几个tmux脚本批量维护会话列表,快速重启、切换、甚至分享部分会话都是非常方便的。可能会有人说为什么不用Tmux Resurrect呢?是的,Tmux Resurrect很好,一键恢复也很诱人,但是对于一个维护大量tmux会话的用户而言,一键恢复可能不见得好,分批次恢复可能是他(她)更想要的,脚本化的tmux就很好地满足了这点。

脚本中创建tmux会话时,由于不需要开启可视化界面,需要输入-d参数指定会话后台运行,如下。

1
tmux new -s init -d # 后台创建一个名称为init的会话
Copied!

新建的会话,建议重命令会话的窗口名称,以便后续维护。

1
2
# 重命名init会话的第一个窗口名称为service
tmux rename-window -t "init:1" service
Copied!

现在,可以在刚才的窗口中输入指令了。

1
2
# 切换到指定目录并运行python服务
tmux send -t "init:service" "cd ~/workspace/language/python/;python2.7 server.py" Enter
Copied!

一个面板占用一个窗口可能太浪费了,我们来分个屏吧。

1
2
3
4
# 默认上下分屏
tmux split-window -t "init:service"
# 切换到指定目录并运行node服务
tmux send -t "init:service" 'cd ~/data/louiszhai/node-webserver/;npm start' Enter
Copied!

现在一个窗口拥有上下两个面板,是时候创建一个新的窗口来运行更多的程序了。

1
2
3
4
# 新建一个名称为tool的窗口
tmux neww -a -n tool -t init # neww等同于new window
# 运行weinre调试工具
tmux send -t "init:tool" "weinre --httpPort 8881 --boundHost -all-" Enter
Copied!

另外新建窗口运行程序,有更方便的方式,比如使用 processes 选项。

1
2
tmux neww-n processes ls # 新建窗口并执行命令,命令执行结束后窗口将关闭
tmux neww-n processes top # 由于top命令持续在前台运行,因此窗口将保留,直到top命令退出
Copied!

新的窗口,我们尝试下水平分屏。

1
2
3
4
# 水平分屏
tmux split-window -h -t "init:tool"
# 切换到指定目录并启用aria2 web管理后台
tmux send -t "init:tool" "cd ~/data/tools/AriaNg/dist/;python -m SimpleHTTPServer 10108" Enter
Copied!

类似的脚本,我们可以编写一打,这样快速重启、切换、甚至分享会话都将更加便捷。

十. 开机自动启用Web服务器

Licensed under CC BY-NC-SA 4.0
最后更新于 2024年5月24日 16:57
发表了90篇文章 · 总计613.28k字
本站总访问量本站访客数人次

目录