# 第 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 會話。使用起來就像在普通終端中一樣,在里面執行任何終端命令都和普通終端差不多。

圖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)。

圖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 會話)那樣。

圖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 的幾個默認面板布局 |