介绍

关于终端模拟器,在KDE环境我已经用konsole用了几年了,在Gnome环境就用Terminal,但是总觉得多个任务处理时很麻烦,不停的切换终端,特别是工作环境中使用的Linux限制太多,而且还得ssh远程服务器。以前知道screen可以实现终端复用,但是一直没有尝试过,最近想好好配置一些常用的工具和环境以提高效率,看到网上到处对tmux一片大赞,准备试试这个软件。

tmux是一个优秀的终端复用工具,源自OpenBSD,采用BSD授权。使用tume最明显的感受是通过一个终端登录远程主机并运行tmux后,在其中可以开启多个控制台,也就是所谓的多窗口分割。

tmux的特性中,对我最有吸引的是:

安装

我使用的系统是openSUSE,直接通过zypper安装,安装完成后运行tmux就可以启动了。

zypper in tmux

基本元素

tmux中有几个基本元素:会话(session)、窗口(window)和面板(pane)。这篇文章对这几个概念解释的很清楚。

tmux使用了C/S模型,运行tmux就开启了一个服务器,并且会自动创建一个新的会话。tmux会话可以包含一组窗口,通常把同一个任务的多个窗口保存在一个会话中,而且可以给会话命名以便在不同会话间切换。

窗口可以在屏幕上直观的显示,每个窗口可以包含多个面板,而且窗口也有自己的编号,当前也可以切换不同窗口。

而面板是在单个窗口上划分出的更小的窗格,一个窗口可以划分出多个小面板,而且可以自由排列。

操作

tmux的操作几乎都是通过键盘中的组合按键实现,tmux有一个快捷键前缀(意思就是说当按下这个前缀按键时,tmux会认为接下来的按键是发送给tmux的,并将其当作特定命令解释执行),默认的快捷键前缀是Ctrl + b

下面的按键中的prefix都表示快捷键前缀,如果没有重定义快捷键前缀,则为Ctrl + b

系统操作

按键 操作
prefix ? 显示快捷键帮助
prefix d 离开并保存会话,返回shell界面;这时tmux仍在后台运行,可以通过tmux attach进入到指定的会话
prefix D 选择要脱离的会话,在同时开启多个会话时使用
prefix Ctrl+z 挂起当前会话,暂时返回shell,再次输入fg可以返回tmux
prefix : 进入命令行模式,可以输入支持的命令,如kill-server关闭服务器,命令tmux list-commands可以列出所有命令
prefix [ 进入复制模式,此时操作和vi相同,按q/ESC退出
prefix ] 粘贴最后一次复制的文本内容
prefix = 从一个交互式列表中选择要粘贴到哪个buffer
prefix - 删除最后一次复制的文本内容
prefix PgUp 向上回滚窗口历史记录
prefix PgDn 向下回滚窗口历史记录

会话(session)相关

按键 操作
prefix s 以菜单方式显示会话,可以查看或切换会话
prefix $ 重命名当前的会话
prefix ( 切换到前一个会话
prefix ) 切换到后一个会话

窗口(window)相关

按键 操作
prefix w 以菜单方式显示窗口,可以查看或者切换窗口
prefix c 新建窗口
prefix & 关闭窗口
prefix 0-9 使用窗口号切换窗口
prefix p 选择前一个窗口
prefix n 选择下一个窗口
prefix l 切换到最后使用的窗口
prefix , 重命名当前窗口
prefix . 移动当前窗口,相当于窗口重排序,可以将当前窗口移动到其他session
prefix f 在所有窗口中查找指定文本

面板(pane)相关

按键 操作
prefix " 横向分割窗口,在垂直方向上拆分出一个新面板
prefix % 纵向分割窗口,在水平方向上拆分出一个新面板
prefix x 关闭面板
prefix o 切换到下一个面板
prefix q 查看所有面板的编号
prefix z 暂时把一个面板放到最大,再次按下恢复之前的大小和位置
prefix 方向键 移动光标选择面板
prefix Ctrl+方向键 以1个单元格为单位移动边缘调整面板大小
prefix Alt+方向键 以5个单元格为单位移动边缘调整面但大小
prefix ; 跳到最后一个使用的面板
prefix ! 把当前面板变成一个新窗口,即新建一个窗口切仅包含当前面板
prefix Space 在预置的面板布局中循环切换;依次包括even-horizontal、even-vertical、main-horizontal、main-vertical、tiled
prefix { 交换当前面板和前一个面板
prefix } 交换当前面板和后一个面板

配置

安装完tmux默认没有配置文件,所有的配置以及快捷键绑定都是用的tumx默认值,不过可以在文件~/.tmux.conf总修改tmux的默认配置。

参考tmux手册,可以看到所有tmux的可配置项,例如:

# 增强色彩
set -g default-terminal 'screen-256color'

# 窗口支持UTF-8
setw -g utf8 on

# 设置使用vi命令模式,如果习惯使用emacs,可以设置为emacs
setw -g mode-keys vi

# 使用hjkl键在面板间跳转(默认是用方向键),源自vim操作习惯
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
# 使用Ctrl+h和Ctrl+l切换上一个和下一个窗口
bind-key -r C-h select-window -t :-
bind-key -r C-l select-window -t :+

# vi模式的复制粘贴
bind-key -t vi-copy v begin-selection
bind-key -t vi-copy y copy-selection

# 设置Ctrl+s作为备用快捷键前缀(所以命令也可以通过Ctrl+s启用)
set -g prefix2 C-s

# 窗口号从1开始按照窗口顺序编号
set -g base-index 1
set-window-option -g pane-base-index 1

# 关闭任何一个窗口后按照顺序重新编号其他窗口
set -g renumber-windows on

# 显示内容的可滚动范围设置10000行
set -g history-limit 10000

# 启用鼠标支持
bind m \
    set -g mode-mouse on \;\
    set -g mouse-resize-pane on \;\
    set -g mouse-select-pane on \;\
    set -g mouse-select-window on \;\
    display 'Mouse: ON'

# 关闭鼠标支持
bind M \
    set -g mode-mouse off \;\
    set -g mouse-resize-pane off \;\
    set -g mouse-select-pane off \;\
    set -g mouse-select-window off \;\
    display 'Mouse: OFF'

# 状态栏, 使用256色
set -g visual-activity on
setw -g monitor-activity on
set -g status on
set -g status-justify left
set -g status-left-length 100
set -g status-right-length 100
set -g status-attr bold
set -g status-bg colour234
set -g status-fg colour255
set -g status-left '#[fg=colour234,bg=colour203] S:#S #[fg=colour203,bg=colour33]#[fg=colour234,bg=colour33] W:#I #[fg=colour33,bg=colour234]#[default]   '
set -g status-right '#[fg=colour77,bg=colour234]#[fg=colour234,bg=colour77] #(whoami) #[fg=colour37,bg=colour77]#[fg=colour234,bg=colour37] #H #[default]'
setw -g window-status-format '#[fg=colour255,bg=colour236] #I #[fg=colour236,bg=colour238]#[fg=colour255,bg=colour238] #W#F #[fg=colour238,bg=colour234]#[default]'
setw -g window-status-current-format '#[fg=colour234,bg=colour220] #I #[fg=colour220,bg=colour227]#[fg=colour234,bg=colour227] #W#F #[fg=colour227,bg=colour234]#[default]'

配置后tmux运行效果如下图:

tmux sample

我在github上维护了一个dotfiles仓库,在这里可以找到我使用的最新的tmux配置文件。

更改了tmux配置文件后,可以用下面的方式生效:

  1. 新建一个会话(session),~/.tmux.conf的内容就在这个新的会话中生效了。
  2. 在当前会话中执行prefix :source-file ~/.tmux.conf,则配置在当前会话生效。

使用

基本用法

直接执行tmux不跟参数时,tmux默认以参数“new-session”启动,会创建一个新的会话,该会话包含一个窗口,窗口中仅有一个面板。

退出会话时tmux会自动保存该会话,而且tmux服务器依然在后台运行。之后可以使用tmux attach命令重新连接会话。

tmux list-sessions			# 列出所有会话
tmux attach-session			# 连接最近最常用的会话
tmux attach-session -t [session]	# 连接到指定的会话

tmux的命令很多都有缩写形式,可以参见tmux手册查看具体的命令缩写,比如上面的命令用缩写形式如下。而且tmux还会智能尝试匹配命令,只要给出的命令字符串可以唯一匹配到一个有效的命令tmux就会执行对应的命令,比如只给出tmux a,tmux依然会执行tmux attach命令。

tmux ls
tmux attach
tmux attach -t [session]

复制粘贴

tmux的复制模式很好用,类似于vim中的visual模式。

首先,按下prefix [进入复制模式,(之前的配置中选择使用vim按键模式且重新绑定了复制键),移动光标到需要复制的位置开始处,按下v键开始选择,再次移动光标到所需复制内容结尾处,然后按下y键复制。

粘贴是通过prefix ]快捷键实现的。

远程工作

推荐远程环境如下使用tmux:

  1. ssh登录远程主机
  2. 运行tmux new-session -s <name>创建一个名为name的会话
  3. 创建窗口及面板
  4. 若网络连接中断或者重新登录远程主机,使用tmux a -t <name>恢复工作环境

结对编程

tmux支持结对编程,简单说就是在同一个服务器上的同一个账户运行tmux服务器,然后两个人从不同主机使用这个相同的帐号登录这台服务器并连接到相同的会话中,那么其中一个人做的改动会即时反映到另一个人的终端上。

最后,开启tmux,尽情的享用吧!


参考:

[1] http://blog.guorongfei.com/2015/08/15/tmux-tutorial/

[2] http://mingxinglai.com/cn/2012/09/tmux/

[3] http://cenalulu.github.io/linux/tmux/

[4] http://longgeek.com/2013/01/22/linux-terminal-killer-programmers-tool-tmux/