碎碎念

  1. 最近总觉得自己的开发效率有点低。每次连上服务器做点事,跑个代码,结果不小心误关了窗口,导致SSH断开,辛辛苦苦跑的程序又要重新跑一遍,心态直接爆炸。
  2. 有时候我需要多开窗口连接同一个服务器,比如一个看日志,一个看数据,还有一个看代码,但是每次重新打开我的电脑时,这些窗口都需要重新连接一次,很不方便。
  3. 然后我就在想:有没有那种可以让我一个窗口里开好几个终端,还能让我中途离开、断网都不怕的工具?通过这几个关键字,我找到了tmux,它很好地解决了这些问题,于是在这里安利给大家。

软件介绍

tmux是一个Linux上的终端复用器(terminal multiplexer),简单来说,它可以让你在一个终端窗口中同时运行多个会话,并且可以随时断开连接后再恢复。它的核心功能如下:

  1. 会话管理:一个 tmux 会话里可以有多个窗口(像标签页),每个窗口里又可以分多个窗格(像屏幕分区)。
  2. 断开/重连:你可以离开当前 tmux 会话,无论多久,只要服务器不重启,都可以通过一个连接回来继续用。
  3. 快捷键操作:很多操作可以通过快捷键一键搞定。
  4. 定制配置:用户可以自定义配置文件,十分方便。

软件安装

  1. 目前大部分Linux发行版的包管理工具都可以直接安装tmux,以下以Ubuntu和ArchLinux为例展示其安装命令。
  2. 或者也可以直接访问官网,查看如何安装。官网地址:https://github.com/tmux/tmux

Ubuntu

执行以下命令即可

apt-get install tmux

ArchLinux

执行以下命令即可

pacman -S tmux

基本使用

  1. 安装成功后,直接在命令行输入以下命令即可进入到tmux界面。
    tmux
    
  2. 在tmux界面中,底部有一个状态栏。状态栏的左侧是窗口信息(编号和名称),右侧是系统信息。
  3. 输入 exit命令,就可以退出tmux窗口。
  4. tmux有很多命令和快捷键,但由于默认快捷键我认为不是很方便操作,所以就自定义了配置文件来修改默认快捷键。因此我不会过多介绍命令和快捷键,而是通过后文的配置文件和相关说明来介绍。

核心概念

tmux 的核心概念就三个:Session、Window、Pane,它们就像是三层结构的“房子”,每层都有各自的功能。

🏠 Session(会话)
  └── 📂 Window(窗口 / 标签页)
        └── 🧱 Pane(窗格 / 分屏)

Session(会话)

  • 它是tmux的最顶层单位,可以把它理解为你开启的一个“项目空间”或者“工作场景”。你每次在命令行执行tmux时都会创建一个新的Session,每个 Session是独立的空间,互不干扰。
  • 你可以随时离开当前Session,然后下次再重新连接回来。这个Session会在你离开时仍然保持后台运行,里面运行的程序在离开时也不会中断运行。
  • 以下是一些常用的与Session相关的命令。
    tmux new -s mysession       # 创建一个名为 mysession 的 session
    tmux ls                     # 列出所有 session
    tmux attach -t mysession    # 连接到名为 mysession 的 session
    tmux detach                 # 脱离当前session
    tmux a                      # 连接上一个脱离的session
    

Window(窗口)

  • 每个 Session 下面可以有很多个 Window,就像浏览器的标签页一样。
  • 每个 Window 都是一个独立的 shell 环境,可以用来区分不同任务。

Panel(窗格)

  • 每个 Window 可以再拆分为多个 Panel,也就是“分屏”,可以同时看多个终端任务。
  • 竖着分、横着分都可以。可以在各个 panel 之间切换、调整大小、甚至关掉某一个。

配置文件

  1. tmux有大量的快捷键,为了避免与现有快捷键冲突,很多快捷键都需要通过前缀键(prefix)唤起。默认情况下前缀键为 Ctrl+b,也就是说每次使用快捷键前,都必须按下 Ctrl+b才可以。比如脱离当前Session的快捷键为 Ctrl+b d。在我的配置文件中,我将前缀键改为 Ctrl+s,你也可以自己定义其他键为前缀键。
  2. 我的配置在打开tmux时,会默认启动Shell为Fish,这需要你提前安装Fish。如果你不喜欢,则删掉带有 fish那一行配置即可。
  3. 配置文件的保存路径以及文件名为 ~/.tmux.conf
  4. 在将文件创建或拷贝过去后,需要执行以下命令重启tmux,让配置生效。
    tmux kill-server
    tmux
    
  5. 以下是我的配置文件,每项配置都附有注释说明
    # -- general
    setw -g xterm-keys on                   # 启用对 xterm 风格键的支持
    set -s escape-time 0                    # 设置 Esc 键的响应时间为 0(立即触发)
    set -sg repeat-time 300                 # 设置重复按键的触发时间间隔为 300 毫秒
    set -s focus-events on                  # 启用窗口焦点变化事件
    set -g mouse on                         # 启用鼠标支持
    
    set -q -g status-utf8 on                # 启用状态栏的 UTF-8 支持(旧版兼容)
    setw -q -g utf8 on                      # 启用窗口的 UTF-8 支持(旧版兼容)
    
    set -g visual-activity off              # 禁用窗口视觉活动通知
    setw -g monitor-activity off            # 禁用窗口活动监控
    setw -g monitor-bell off                # 禁用窗口提示铃声
    
    set -g history-limit 10000              # 设置命令历史记录限制为 10,000 行
    
    set-option -g default-shell "/usr/bin/fish"  # 设置fish为默认shell
    
    # reload configuration
    bind r source-file ~/.tmux.conf \; display '~/.tmux.conf sourced' 
                                            # 绑定 prefix+r 重新加载 tmux 配置文件
    
    set -ga update-environment '\
    DISPLAY DBUS_SESSION_BUS_ADDRESS \
    QT_IM_MODULE QT_QPA_PLATFORMTHEME \
    SESSION_MANAGER \
    XDG_CONFIG_HOME XDG_CACHE_HOME XDG_DATA_HOME\
    XDG_MENU_PREFIX XDG_RUNTIME_DIR XDG_SESSION_CLASS \
    XDG_SESSION_DESKTOP XDG_SESSION_TYPE XDG_CURRENT_DESKTOP \
    XMODIFIERS \
    FZF_DEFAULT_OPTS \
    '                                       # 指定需要同步的环境变量
    
    # -- prefix
    unbind C-b                             # 解除默认的前缀键 Ctrl-b
    set -g prefix 'C-s'                    # 将前缀键改为 Ctrl-s
    
    # -- display
    set -g base-index 1                    # 窗口编号从 1 开始
    setw -g pane-base-index 1              # 窗格编号从 1 开始
    
    setw -g automatic-rename on            # 启用窗口的自动重命名
    set -g renumber-windows on             # 启用窗口编号的重新排序
    
    set -g set-titles on                   # 启用终端标题设置
    set -g display-panes-time 2000         # 设置窗格显示的持续时间为 2 秒
    set -g display-time 2000               # 设置状态信息显示的持续时间为 2 秒
    set -g status-interval 1               # 设置状态栏刷新间隔为 1 秒
    
    # -- navigation
    bind C-c new-session                   # 绑定 prefix+Ctrl-c 创建新会话
    
    # window management
    bind -n M-o new-window -c "#{pane_current_path}" 
                                            # 绑定 Alt-o 在当前路径下创建新窗口
    bind -n M-O break-pane                 # 绑定 Alt-Shift-o 分离窗格为新窗口
    bind -n M-Q kill-pane                  # 绑定 Alt-Shift-q 关闭窗格
    
    # window navigation
    unbind n                               # 解除默认的下一个窗口快捷键
    unbind p                               # 解除默认的上一个窗口快捷键
    unbind 1                               # 解除数字快捷键绑定(1-9、0)
    unbind 2
    unbind 3
    unbind 4
    unbind 5
    unbind 6
    unbind 7
    unbind 8
    unbind 9
    unbind 0
    bind -r C-p previous-window            # 绑定 prefix+Ctrl-p 切换到上一个窗口
    bind -r C-n next-window                # 绑定 prefix+Ctrl-n 切换到下一个窗口
    
    bind -n M-1 select-window -t 1         # 绑定 Alt-1 切换到窗口 1
    bind -n M-2 select-window -t 2         # 绑定 Alt-2 切换到窗口 2
    bind -n M-3 select-window -t 3         # 绑定 Alt-3 切换到窗口 3
    bind -n M-4 select-window -t 4         # 绑定 Alt-4 切换到窗口 4
    bind -n M-5 select-window -t 5         # 绑定 Alt-5 切换到窗口 5
    bind -n M-6 select-window -t 6         # 绑定 Alt-6 切换到窗口 6
    bind -n M-7 select-window -t 7         # 绑定 Alt-7 切换到窗口 7
    bind -n M-8 select-window -t 8         # 绑定 Alt-8 切换到窗口 8
    bind -n M-9 select-window -t 9         # 绑定 Alt-9 切换到窗口 9
    
    bind -n M-! join-pane -t :1            # 绑定 Alt-! 将窗格移至窗口 1
    bind -n M-@ join-pane -t :2            # 绑定 Alt-@ 将窗格移至窗口 2
    bind -n 'M-#' join-pane -t :3          # 绑定 Alt-# 将窗格移至窗口 3
    bind -n 'M-$' join-pane -t :4          # 绑定 Alt-$ 将窗格移至窗口 4
    bind -n M-% join-pane -t :5            # 绑定 Alt-% 将窗格移至窗口 5
    bind -n M-^ join-pane -t :6            # 绑定 Alt-^ 将窗格移至窗口 6
    bind -n M-& join-pane -t :7            # 绑定 Alt-& 将窗格移至窗口 7
    bind -n M-* join-pane -t :8            # 绑定 Alt-* 将窗格移至窗口 8
    bind -n M-( join-pane -t :9            # 绑定 Alt-( 将窗格移至窗口 9
    
    bind i split-window -vb -c "#{pane_current_path}" 
                                            # 绑定 prefix+i 垂直向下拆分窗口,并保持当前路径
    bind k split-window -v -c "#{pane_current_path}"  
                                            # 绑定 prefix+k 垂直向上拆分窗口,并保持当前路径
    bind j split-window -hb -c "#{pane_current_path}" 
                                            # 绑定 prefix+j 水平向左拆分窗口,并保持当前路径
    bind l split-window -h -c "#{pane_current_path}"  
                                            # 绑定 prefix+l 水平向右拆分窗口,并保持当前路径
    
    bind -n M-f resize-pane -Z             # 绑定 Alt-f 放大当前窗格
    
    # pane navigation
    bind 1 select-pane -t:.1               # 绑定 prefix+1 选择第一个窗格
    bind 2 select-pane -t:.2               # 绑定 prefix+2 选择第二个窗格
    bind 3 select-pane -t:.3               # 绑定 prefix+3 选择第三个窗格
    bind 4 select-pane -t:.4               # 绑定 prefix+4 选择第四个窗格
    bind 5 select-pane -t:.5               # 绑定 prefix+5 选择第五个窗格
    bind 6 select-pane -t:.6               # 绑定 prefix+6 选择第六个窗格
    bind 7 select-pane -t:.7               # 绑定 prefix+7 选择第七个窗格
    bind 8 select-pane -t:.8               # 绑定 prefix+8 选择第八个窗格
    bind 9 select-pane -t:.9               # 绑定 prefix+9 选择第九个窗格
    bind 0 select-pane -t:.10              # 绑定 prefix+0 选择第十个窗格
    bind -n M-j select-pane -L             # 绑定 Alt-j 切换到左侧窗格
    bind -n M-k select-pane -D             # 绑定 Alt-k 切换到下方窗格
    bind -n M-i select-pane -U             # 绑定 Alt-i 切换到上方窗格
    bind -n M-l select-pane -R             # 绑定 Alt-l 切换到右侧窗格
    bind > swap-pane -D                    # 绑定 prefix+> 与下方窗格交换
    bind < swap-pane -U                    # 绑定 prefix+< 与上方窗格交换
    bind | swap-pane                       # 绑定 prefix+| 交换两个窗格
    bind -n M-Space next-layout            # 绑定 Alt-Space 切换到下一个窗格布局
    
    bind W choose-tree -Z                  # 绑定 prefix+W 打开树状结构选择窗口或窗格
    bind S choose-tree 'move-pane -v -s "%%"' 
                                            # 绑定 prefix+S 垂直移动窗格
    bind V choose-tree 'move-pane -h -s "%%"' 
                                            # 绑定 prefix+V 水平移动窗格
    
    # pane resizing
    bind -n M-J resize-pane -L 3           # 绑定 Alt-J 将窗格向左缩小 3 单位
    bind -n M-K resize-pane -D 3           # 绑定 Alt-K 将窗格向下缩小 3 单位
    bind -n M-I resize-pane -U 3           # 绑定 Alt-I 将窗格向上增大 3 单位
    bind -n M-L resize-pane -R 3           # 绑定 Alt-L 将窗格向右增大 3 单位
    
    set -g status-keys emacs               # 设置状态栏快捷键为 Emacs 风格
    set -g mode-keys vi                    # 设置复制模式的快捷键为 Vi 风格
    
    bind -n M-v copy-mode                  # 绑定 Alt-v 进入复制模式
    
    bind b list-buffers                    # 绑定 prefix+b 显示缓冲区列表
    bind p paste-buffer                    # 绑定 prefix+p 粘贴缓冲区内容
    
    # -- toggle_syn_input
    bind C-g if-shell '[[ $(tmux showw synchronize-panes | cut -d\  -f2) == "on" ]]' \
    'setw synchronize-panes off; set -g pane-border-style fg=magenta' \
    'setw synchronize-panes on; set -g pane-border-style fg=red'
                                            # 绑定 prefix+Ctrl-g 切换同步输入模式,并改变窗格边框颜色
    
    
  6. 以下是关于该配置文件的说明,你也可以通过配置文件中的注释去了解。
  • prefix(Ctrl-s)
    • 默认的 tmux 前缀键,所有以 prefix+键 组合的快捷键都需要先按 Ctrl-s
  • 重新加载配置
    • prefix+r:重新加载 ~/.tmux.conf 配置文件,并显示提示信息。
  • 进入复制模式
    • Alt-v:进入复制模式。
  • 显示缓冲区列表
    • prefix+b:显示所有缓冲区列表。
  • 粘贴缓冲区内容
    • prefix+p:粘贴缓冲区内容到当前窗格。
  • 创建新会话
    • prefix+Ctrl-c:创建一个新会话。
  • 新建窗口
    • Alt-o:在当前路径下新建一个窗口。
  • 拆分窗口为独立会话
    • Alt-O:将当前窗口拆分成独立会话。
  • 关闭当前窗口
    • Alt-Q:关闭当前窗格。
  • 切换窗口
    • prefix+Ctrl-p:切换到上一个窗口。
    • prefix+Ctrl-n:切换到下一个窗口。
  • 直接选择窗口
    • Alt-1~9:快速切换到对应编号的窗口(1~9)。
  • 将窗格移动到对应窗口
    • Alt-!:将当前窗格移动到窗口 1。
    • Alt-@:将当前窗格移动到窗口 2。
    • 其他以 Alt+Shift+数字键的组合对应窗口 3~9。
  • 拆分窗格
    • prefix+i:垂直拆分窗格(下方)。
    • prefix+k:垂直拆分窗格(上方)。
    • prefix+j:水平拆分窗格(左侧)。
    • prefix+l:水平拆分窗格(右侧)。
  • 调整窗格大小
    • Alt-J:向左调整窗格宽度 3 单位。
    • Alt-K:向下调整窗格高度 3 单位。
    • Alt-I:向上调整窗格高度 3 单位。
    • Alt-L:向右调整窗格宽度 3 单位。
  • 全屏窗格
    • Alt-f:全屏或恢复当前窗格大小。
  • 切换窗格布局
    • Alt-Space:切换到下一个窗格布局。
  • 选择窗格
    • prefix+1~9:快速切换到编号对应的窗格。
    • Alt-j:切换到左侧窗格。
    • Alt-k:切换到下方窗格。
    • Alt-i:切换到上方窗格。
    • Alt-l:切换到右侧窗格。
  • 交换窗格位置
    • prefix+>:与下方窗格交换位置。
    • prefix+<:与上方窗格交换位置。
    • prefix+|:交换当前窗格与目标窗格。
  • 同步窗格输入
    • prefix+Ctrl-g:切换同步输入模式,同时调整窗格边框颜色(红色表示开启,同步)。

参考资料

Tmux 使用教程

终端神器tmux:多任务管理大师