# 第 1 章 基础知识
一旦你熟悉了 tmux 后, 它就像一个加速器一样加速你的工作效率。在这个章节你会了解到 tmux 的基本特性,包括使用会话,窗口和面板管理你的程序。这些简单的概念正是组成 tmux 的重要基石,是它们让 tmux 成为开发人员和系统管理员的手中利器。
在学习如何使用这些特性之前,你需要确保 tmux 已被安装。
## 1.1 安装 tmux
你可以通过两种方式安装 tmux:使用包管理器安装,或者从源码编译构建安装。
无论选择哪种方式,都要确保安装的 tmux 是 1.6 或更新版本,本书使用的是 tmux 1.6 版。早期的版本可能不支持我们将要学习的一些特性。
### 通过包管理器安装
tmux 可以在多种包管理器中安装。在 OS X 系统,你可以通过 Homebrew 或 Macports 安装 tmux。如何安装包管理器不在本书的范围内,请为你选择的管理器查阅相关资料。无论你选择了哪种包管理器,可能都会用到 Xcode,可以通过 Mac 电脑的随机光盘安装 Xcode,或是通过 Mac App Store 安装。
如果你使用的是 Homebrew,可以通过以下命令安装:
```
$ brew install tmux
```
如果你使用的是 MacPorts,可以通过以下命令安装:
```
$ sudo port install tmux
```
对于 Ubuntu 用户,可以通过以下命令安装:
```
$ sudo apt-get install tmux
```
在终端中执行以下命令来确认 tmux 版本号及安装是否正确:
```
$ tmux -V
```
tmux 1.6
由于包管理器的原因,你可能无法安装最近的 tmux 版本,这意味着你需要通过源码编译安装。下面我们看看如何安装。
### 从源码安装
在 Mac OS X 与 Linux 编译安装 tmux 的过程是一样的,两者都需要 GCC 编译器。
Mac 用户需要安装 Xcode,可以在随机光盘或 Mac App Store 中获取。
Linux 用户,自带的包管理器往往已经内置了 GCC 编译器。对于 Ubuntu 系统,只需要执行以下命令就可以安装好所有编译器:
```
$ sudo apt-get install build-essential
```
tmux 还依赖 libevent 和 ncurses,请事先安装好。对于 Ubuntu 系统,可以使用以下命令安装:
```
$ sudo apt-get install libevent-dev libncurses5-dev
```
编译器与软件包依赖安装后,下载 tmux 源码,执行以下命令解压并安装:
```
$ tar -zxvf tmux-1.6.tar.gz
$ cd tmux-1.6
$ ./configure
$ make
$ sudo make install
```
你可以执行以下命令验证安装是否成功,该命令会返回当前 tmux 版本:
```
$ tmux -V
```
tmux 1.6
现在 tmux 已经安装完成了,下面我们开始通过一个基础的会话展开对 tmux 核心功能的探索。
## 1.2 开始使用 tmux
在终端中只要执行以下命令就可以启动 tmux:
```
$ tmux
```
然后在屏幕上会出现一个类似图 2 的界面,这就是一个新的 tmux 会话。使用起来就像在普通终端中一样,在里面执行任何终端命令都和普通终端差不多。
![document/2015-09-09/55efaa917a9e2](https://box.kancloud.cn/document_2015-09-09_55efaa917a9e2.jpg)
图2 - 新的 tmux 会话
要关闭 tmux 会话,只需在会话中输入:
```
$ exit
```
这样就可以关闭 tmux 并返回到标准终端中。
但是,除非你只是很短暂地用一下 tmux,否则我们不建议你使用这种方式来使用会话。我们在后面会说明如何创建一种“命名会话(named session)”来取代这种方式。
### 创建命名会话
我们可以在一台计算机上创建多个会话,并且通过为每个会话指定一个唯一的名称来管理它们。我们现在就来创建一个叫做 basic 的会话:
```
$ tmux new-session -s basic
```
这个命令可以简化为:
```
$ tmux new -s basic
```
这种简化命令会在本书的后面一直使用。
执行这条命令后我们会进入到一个全新的会话中,但是我们并不会感到与之前进入 tmux 会话的方式有何不同之处。如果我们输入 `exit` 命令,也会返回到标准终端里。
然而命名会话会在我们想让 tmux 在后台运行而又不想关闭 tmux 时变得非常方便,我们接下来会讨论这部分内容。在继续之前,请输入命令来离开 tmux:
```
$ exit
```
## 1.3 分离和连接会话
tmux 的一个最大优势就是启动 tmux 环境并执行各种程序或进程时,可以通过从会话“分离(detaching)”让 tmux 在后台运行。
如果我们关闭了一个普通的终端会话,那么这个会话中的所有程序都会被杀死。但是从一个 tmux 会话分离时,实际上并没有关闭 tmux。在这个会话中运行的程序仍然在运行。然后可以在任何想要的时候再“连接(attaching)”上这个会话,你会发现所有的界面(现场)就和你分离会话时一模一样。下面对这个功能的演示中,我们会创建一个命名会话,启动一个程序,然后从这个会话中分离。首先创建这个 basic 会话:
```
$ tmux new -s basic
```
然后,在这个 tmux 会话中执行一个 `top` 命令,它用来监测计算机的内存和 CPU 使用情况,就像这样:
```
$ top
```
现在终端里就有与图3(tmux 中运行的 top 命令)类似的界面了。这时在键盘上同时按下 `CTRL-b` 键,然后再按下 `d` 键,这样就从 tmux 会话中分离出来,返回到标准终端界面里了。在后面我们会学习如何快速地返回到 basic 会话中,但是首先我们来谈谈命令前缀(command prefix)。
![document/2015-09-09/55efaab0e03ae](https://box.kancloud.cn/document_2015-09-09_55efaab0e03ae.jpg)
图3 - 在 tmux 中执行 top 命令
### 命令前缀
由于我们的程序是在 tmux 环境里运行的,因此需要一种方式来告诉 tmux 当前所输入的命令是为了让 tmux 去执行而不是 tmux 里的应用程序去执行,这就是 `CTRL-b` 组合键的作用。
当我们想要从 tmux 会话中分离时,可以先按 `CTRL-b` 键,然后再按 `d` 键(d=detach,译者注)。在执行 tmux 命令时,每次都要先按下这个 `CTRL-b` 组合键,然后再按下 tmux 命令键(如 `d`),因此我们把这个组合键称为命令前缀。有一点非常重要:并不是把前缀键和命令键一起按下,而是先同时按下 `CTRL` 键和 `b` 键,然后松开这两个键,然后再快速地按下要让 tmux 执行的命令键。
在本书的剩余部分中,我们会使用符号 `PREFIX` 来表示命令前缀,比如 `PREFIX d` 命令表示从一个 tmux 会话分离。在第二章,我们会将前缀重新映射为一个更加方便的组合键,但是目前,我们还是使用默认的组合键。
现在,我们来学习如何回到刚才分离的那个 tmux 会话。在这之前,请将你的终端窗口关闭。
### 重新连接已有会话
我们之前新建了一个 tmux 会话,在会话中运行了一个程序,然后从这个会话中分离出来,最后甚至关闭了终端窗口,但是这个 tmux 会话依然在运行,而 top 命令也没有停止运行。
在一个新的终端窗口里执行以下命令列出当前存在的 tmux 会话:
```
$ tmux list-sessions
```
这个命令可以简化为:
```
$ tmux ls
```
这条命令会展示目前有一个会话正在运行:
```
basic: 1 windows (created Mon Jan 30 16:58:26 2012) [105x25]
```
要想连接到这个会话,可以使用 attach 命令。如果目前只有一个会话在运行,可以用下面这个命令来连接它:
```
$ tmux attach
```
这样就可以重新连接到这个 tmux 会话中。如果有 2 个或多个 tmux 会话在运行,操作会稍微麻烦一些。我们先用命令 `PREFIX d` 从 basic 会话中分离出来。
现在,用这个命令创建一个新的 tmux 会话并让它在后台运行:
```
$ tmux new -s second_session -d
```
再列出当前已有的会话列表,就会看见类似如下:
```
$ tmux ls
basic: 1 windows (created Mon Jan 30 16:58:26 2012) [105x25]
second_session: 1 windows (created Mon Jan 30 17:49:21 2012) [105x25]
```
用 `-t` 参数加上会话名称来连接到指定的会话,如连接到 second_session 这个会话:
```
$ tmux attach -t second_session
```
我们可以用前面提到的命令从一个会话中分离出来,然后再连接到另一个会话里。在后续章节你会学到在活动会话之间切换的其它方式。但是现在,我们先学习如何杀死一个活动会话。
### 杀死会话
可以在一个会话中使用 `exit` 命令来杀死这个会话,也可以使用 kill-session 命令杀死指定会话:
```
$ tmux kill-session -t basic
$ tmux kill-session -t second_session
```
当一个会话中的程序处于挂起状态时这个命令会很有用。
此时,如果再次列出当前已有会话,会得到这样的信息:
```
$ tmux ls
failed to connect to server: Connection refused
```
这是因为目前没有 tmux 会话在运行,因此 tmux 本身也没有运行,所以它无法处理这个请求。
现在你已经学会了创建并使用会话的基础知识了,下面我们来学习如何在一个会话中同时运行多个程序或命令。
## 1.4 使用窗口
在一个 tmux 会话中同时运行多个命令或同时执行多个程序的情景非常普遍。可以通过窗口(window)来管理它们,窗口的功能就像现代图形终端模拟器或 web 浏览器的标签页。
一个新的 tmux 窗口被创建时,tmux 环境(environment)会为配置一个初始化的窗口。我们可以创建任意多的窗口,而且在分离与连接会话过程中它们会一直存在。
现在我们来创建一个包含 2 个窗口的新会话。第一个窗口只显示终端提示符,而第二个窗口将会执行 top 命令。可以用以下命令来创建一个叫做 windows 的会话:
```
$ tmux new -s windows -n shell
```
命令中的 `-n` 参数可以让 tmux 把第一个窗口命名为 shell,方便我们辨识这个窗口。
接下来再为这个会话添加一个窗口。
### 创建并命名窗口
要在当前会话创建一个新的窗口,只需要按下 `PREFIX c` 键。这样创建一个窗口会让 tmux 自动把焦点切换到这个新的窗口里来。在这里可以运行其他程序,在这个窗口里我们运行 `top` 命令。
```
$ top
```
我们已经为第一个窗口命名为 shell,但是第二个窗口似乎看起来叫做 top。由于在创建这个新的窗口时并没有为它命名,因此这个窗口的名称会随着当前运行的程序变化而变化。我们来给这个窗口取个名吧。
要重命名一个窗口,可以通过按下 `PREFIX ,` 键(前缀 + 逗号键,译者注),然后状态栏就会进入重命名窗口的界面。我们将这个窗口命名为 Processes。
可以在一个 tmux 会话中创建任意多个窗口。但是一旦创建了 2 个窗口以上,就必须学会如何在窗口之间切换(move)。
### 在窗口之间切换
我们已经在 tmux 环境中创建了两个窗口,有多种方法可以在这些窗口之间来回切换。如果只有两个窗口,按下 `PREFIX n` 键(n=next,译者注)在已打开窗口之间来回切换。
可以按下 `PREFIX p` 键(p=previous,译者注)切换到上一个窗口。
tmux 的窗口默认有一个编号,从 0 开始计数。按下 `PREFIX 0` 键快速切换到第 1 个窗口,按下 `PREFIX 1` 键切换到第 2 个窗口。从 0 开始计数的窗口数组并不是一成不变的,在第 2 章,你会学到如何让窗口编号不是从 0 开始,而是从 1 开始。
如果窗口超过了 9 个,可以按下 `PREFIX f` 键(f=find,译者注)通过窗口的名称来查找一个窗口(如果窗口已被命名),或者按下 `PREFIX w` 键(w=window,译者注)显示一个可视化的窗口列表,然后再选择其中想要的那个窗口。
从这里,我们可继续创建新的窗口并运行程序。从会话中分离出来后,那些窗口会在下次连接时保持依然保持断开连接时候的环境。
如果要关闭一个窗口,可以在命令提示符后输入 `exit`,或者可以按下 `PREFIX &` 键(&=et=exit,译者注),后者会在状态栏给出一个确认信息询问是否要关闭当前窗口。如果确认并关闭了当前窗口,那么当前窗口的焦点就会转移到上一个窗口。要想完全退出一个 tmux 会话,必须要关闭所有窗口。
在会话中创建窗口这个功能已经非常了不起了,但是我们还能进一步让 tmux 把一个窗口分割成多个面板(pane)。
## 1.5 使用面板
你或许认为能够在不同的窗口之间运行不同的程序已经非常棒了。但是 tmux 还能把窗口分割成多个面板。
下面我们就来创建一个名为 panes 的会话来演示面板的工作机制。
```
$ tmux new -s panes
```
窗口可以以垂直方向或水平方向分割。我们先把窗口在垂直方向分割,然后再在水平方向分割,这样就能得到一个窗口,左边一半是一个大的面板,右边一半是两个并排的小一些的面板,就像图4(一个被切分为多个面板的 tmux 会话)那样。
![document/2015-09-09/55efaacd5f45d](https://box.kancloud.cn/document_2015-09-09_55efaacd5f45d.jpg)
图4 - 一个被切分为多个面板的 tmux 会话
在 tmux 会话中,按下 `PREFIX %` 键(%形似左右各一半,译者注),当前的窗口就会在中间部分从上到下一分为二,在右边的面板里新建第二个面板,而且当前的焦点也会转移到新的面板中。
再按下 `PREFIX "` 键(双引号,译者注),会把这个新的面板再水平地分割为两半。tmux 的默认配置会使得在分割面板时,分割出的两个面板会各占 50% 大小。
要想在这些面板之间来回切换,可以按下 `PREFIX o` 键(o形似循环,译者注)。还可以通过使用 `PREFIX` 前缀键,后面跟随 `UP`、`DOWN`、`LEFT` 或 `RIGHT` 键(上、下、左、右箭头,译者注)在这些面板之间上、下、左、右移动焦点。
通过几次按键,我们已经把一个窗口分割成了带有 3 个面板的工作空间。我们接下来看看如何重新调整这些面板的布局(layout)。
### 面板布局
可以通过逐步调整或使用模版来调整一个面板的大小。使用默认的快捷键来逐步调整面板的大小不得不说让人觉得恶心。在第 2 章,我们会定义一些调整面板大小更加便捷的快捷键。但是目前,我们还是会使用 tmux 的几个默认面板布局中的一个:
* even-horizontal 把所有面板均匀地水平排列,从左到右。
* even-vertical 把所有面板均匀地垂直排列,从上到下。
* main-horizontal 在顶部创建一个非常大的面板,其余面板变为小面板水平地放在底部。
* main-vertical 在左侧创建一个非常大的面板,其余面板变为小面板垂直地放在右侧。
* tiled 把所有面板大小均等地在屏幕上显示。
可以通过按下 `PREFIX SPACEBAR` 键(空格键,译者注)来依次轮回使用这些面板布局。
### 关闭面板
关闭一个面板和关闭终端会话或一个 tmux 窗口的方法相同:只需要在面板里输入 `exit` 命令。还可以通过按下 `PREFIX X` 键(大写 x 键,译者注)杀死一个面板,如果当前窗口只有这一个面板的话,它还会同时关闭这个窗口。
在杀死指定的面板时,你会收到确认提示。如果某个面板被阻塞了,或者你再也用不着这个面板了,不要犹豫,杀死这个面板。
目前为止,你应该已经学会了如何创建新的会话、窗口和面板,并且能在它们之间来回切换了。在继续深入之前,我们先来了解一些 tmux 命令。
## 1.6 使用命令模式
到现在,我们已经可以使用快捷键来创建 tmux 窗口和面板了,这些快捷键都只是 tmux 预先定义好的一些组合键。有两种方法来执行 tmux 命令:从终端本身执行,或者在 tmux 状态栏的“命令区域(command area)”执行命令。在第 3 章我们会学到如何在终端里执行 tmux 命令。现在我们来学习如何使用 tmux 的命令模式来创建一些新的窗口和面板。
进入命令模式,你需要在一个正在运行的会话里按下 `PREFIX :` 键(冒号键,译者注)。按下快捷键之后状态栏的颜色会改变,并且你会看到一个命令提示符提示你可以输入命令。我们现在就来使用 new-window 命令创建一个新的窗口,就像这样:
```
new-window -n console
```
使用这个命令而不是使用快捷键来创建新的窗口的好处就是在创建窗口的同时我们附加一个 `-n` 参数给它取个名字。我们现在更进一步,创建一个窗口并让它执行 `top` 命令。在命令模式里输入这个命令:
```
new-window -n processes "top"
```
当我们敲下 `Enter` 时,新窗口就会显示出来并且可以看到 top 命令也在运行,显示了当前计算机正在运行的进程。
在创建 tmux 窗口时给它指定一个初始化的进程是非常便捷的,但是当按下 `q` 键关闭 top 程序时,这个 tmux 窗口也会被一起关闭。如果你想要让 top 程序关闭后窗口依然存在,可以通过配置文件来搞定这个事情,但是最简单的办法莫过于在创建窗口时不要给它指定一个初始化的程序,在创建完窗口之后再执行你想要的命令。
tmux 可以使用命令模式来创建新的窗口,面板和会话,甚至设置一些其它的环境变量配置。在第 2 章,我们会定制一些快捷键来让这些命令用起来更方便、简单。
## 1.7 接下来做什么?
在本章,我们学习了关于 tmux 会话、面板、窗口和命令的基本用法,但是还有很多知识我们没有提到。
按下 `PREFIX ?` 键(问号键,译者注),你可以看到一个关于 tmux 预定义的快捷键列表,以及这些快捷键所绑定的命令。
使用 tmux 时,你应该多想想如何为你的工作创建不同的 tmux 环境。如果你在监控服务器,可以使用 tmux 的面板来创建一个监控面板,让它可以同时显示多个监测脚本和日志文件。
经过之前的学习,我们总结了前面出现的一些命令配置,方便以后查阅。
### 以备查阅
#### 创建会话
| 命令 | 描述 |
| ------------- | ------------- |
| ` tmux new-session` |创建一个未命名的会话。可以简写为 `tmux new` 或者就一个简单的 `tmux` |
| ` tmux new -s development` | 创建一个名为 development 的会话 |
| ` tmux new -s development -n editor` | 创建一个名为 development 的会话并把该会话的第一个窗口命名为 editor |
| ` tmux attach -t development` | 连接到一个名为 development 的会话 |
#### 会话、窗口和面板的默认快捷键
| 快捷键 | 功能 |
| ------------- | ------------- |
| `PREFIX d` | 从一个会话中分离,让该会话在后台运行。 |
| `PREFIX :` | 进入命令模式 |
| `PREFIX c` | 在当前 tmux 会话创建一个新的窗口,是 `new-window` 命令的简写 |
| `PREFIX 0...9` | 根据窗口的编号选择窗口 |
| `PREFIX w` | 显示当前会话中所有窗口的可选择列表 |
| `PREFIX ,` | 显示一个提示符来重命名一个窗口 |
| `PREFIX &` | 杀死当前窗口,带有确认提示 |
| `PREFIX %` | 把当前窗口垂直地一分为二,分割后的两个面板各占 50% 大小 |
| `PREFIX "` | 把当前窗口水平地一分为二,分割后的两个面板各占 50% 大小 |
| `PREFIX o` | 在已打开的面板之间循环移动当前焦点 |
| `PREFIX q` | 短暂地显示每个面板的编号 |
| `PREFIX x` | 关闭当前面板,带有确认提示 |
| `PREFIX SPACE` | 循环地使用 tmux 的几个默认面板布局 |