tmux ,不只是 terminal multiplexer

single_terminal

有在用 terminal 操作的人,肯定都多少會需要『兩個以上 terminal』,如果什麼都不知道的人可能會直接開新視窗:

two_terminals

然後就很有可能會變成這樣:

so_much_terminals

其實不是不好,只是覺得亂,所以其實可以用 ⌘ + t 開新 tab :

terminal_with_tabs

如果你用的是 iTerm2,其實功能也蠻豐富的,但是這不是今天的主題,今天的主題是 tmux

tmux 是啥?

根據 tmux 自己的官方 manualtmux 是個 terminal multiplexertmux 其實是個 executable ,就跟 ls, cp 等等一樣,安裝後(OSX 請滑到最下面我有附上安裝方法)下 tmux 就會跑起來,它會幫你在 tmux 裡面再啟動多個 shell 環境,跟 GUI 多視窗、多 tab 比起來是 multiplex 的部分從 GUI 變成在 terminal 裡面:

tmux_hello

文字介面的 tab ,在 vim 開 tab 也是類似的感覺,但是我的 tmux 也有被我魔改過不是長這樣,可以 curl https://raw.githubusercontent.com/pastleo/dotSetting/master/home/.tmux.conf >> ~/.tmux.conf 變得跟我一樣:

pastleo_tmux_hello

其實主要是有一些我改過的 keybinding,我個人覺得這樣比較好記,待會會提到

tmux 基本操作

tmux # 啟動 tmux 建立一個 session
exit # 離開

你會看到 [exited] ,只是先確保大家知道怎麼離開,一個 session 內所有的 shell 都結束那這個 session 也就隨之結束

prefix

因為一般的 key 必須送進 tmux 裏頭的 shell 或是應用程式,必須先打一個很特殊的 prefix 字元,接下來 tmux 就知道接下來的字元是給 tmux 的指令, tmux 預設 prefix 是 Ctrl + b,而我設定成 Ctrl + a

tmux # 再啟動一次 tmux
ls # 隨便做點事
# 打 prefix 然後輸入 d

使用預設 tmux 設定的人就是打 Ctrl + b 然後 d ,使用我的設定的人請打 Ctrl + a 然後 d ,你會看到 [detached (from session 0)] , session 內的 shell 跟工作狀態都跑到背景去了

tmux a # attatch

就回到原本的 session ,透過這個功能,ssh 到 server 進行操作或甚至開發的工作進度都可以透過這個方法完美保存,而且網路斷線的時候也只是 detatch 而已,之後再連回去就好

start tmux and detatch

我的 prefix 是 Ctrl + a ,因為我把 Cap lock 弄成 Ctrl 鍵,這樣 Ctrl + a 就變得非常好按,而且其實 Ctrl + a 是一個更古老的 terminal mutiplexer - screen 的 prefix ,但是因為 screen 功能比較少所以後來看到 tmux 就立刻切過來用了

multiplex

以下我會用 <prefix> c 表示輸入 prefix 然後輸入 c

  • <prefix> c: 開新 window
  • <prefix> n: 切換到下一個 window
  • <prefix> p: 切換到前一個 window

tmux 的一個 session 可以有多個 window ,一個 window 可以有多個 pane ,可能 window 長得比較像是 tab ,是全畫面的,而 pane 是一個分割畫面(split)

  • <prefix> %: 左右分割畫面
  • <prefix> ": 上下分割畫面
  • <prefix> o: 切換 pane

我自己在 tmux 的 navigation

這些 tmux default 的 window/pane 控制方法有點難記,所以我自己設定了:

  • <prefix> h / Ctrl-h: 切換到前一個 window
  • <prefix> j / Ctrl-j: 切換到下一個 pane
  • <prefix> k / Ctrl-k: 切換到前一個 pane
  • <prefix> l / Ctrl-l: 切換到下一個 window

Ctrl-h 表示直接輸入 Ctrl + h ,有發現什麼嗎?如果熟悉 vim 的移動方式,這些可能比較好記喔

 <prefix> or Ctrl-
   k --- previous pane
 h   l --- previous window / next window
   j --- next pane

除此之外,我直接讓 Ctrl-h/j/k/l 就直接動作,不需要輸入 prefix ,這樣使用起來就更順手囉

navigate in tmux

除了最常用的 navigation 我使用了 vi hjkl 移動的方式之外,移動(reorder) panes, windows 以及分割線我也用了類似的手法,更多請參考我的 .tmux.conf

copy-mode

複製模式?一般的 terminal 應用程式都可往上捲,而在 tmux 內就是靠 copy-mode 來往上看離開視野的 stdout

<prefix> [

就會進入 copy-mode ,這時候這個瞬間會變成一個文字檔供你閱覽,預設用一般的鍵盤上下左右移動 cursor 或是 PageUp, PageDown 捲動,按下 q 離開這個模式

不只是 multiplexer 的部分

在我的設定檔中, Ctrl-v 就可以啟動 copy-mode ,而且我還有這行設定:

setw -g mode-keys vi

這樣 tmux 的 copy-mode 使用 copy-mode-vi 的 keymapping ,我想看到這邊應該可以想的到…感覺有點像用 vi 開啟 stdout 變成一個類似唯讀的文字檔:

  • J / K 捲動
  • q 可以想成 less 的離開
  • / 向下搜尋、 ? 向上搜尋
  • hjkl 移動 cursor
  • e, w, b 就跟 vi 一樣,以 word 為單位移動

可是移動 cursor 可以幹嘛?不是只要捲動就好了嗎?

我想這也是為什麼叫做 copy-mode 的原因,在使用 copy-mode-vi 的狀況下:

  1. 移動 cursor
  2. 按下 Space 開始選擇
  3. 移動 cursor
  4. 按下 Enter 複製
  5. <prefix> ] 貼上,到 stdin

不過用 SpaceEnter 不夠 vim,所以我也補上幾行設定,過程就變成:

  1. 移動 cursor
  2. 按下 v 開始選擇 (V 選擇整行倒是預設就支援不知道為啥)
  3. 移動 cursor
  4. 按下 y 複製
  5. Ctrl-p 貼上,到 stdin

其實這是我最喜歡的 tmux 功能了,在純文字世界工作的時候有時候就是需要去複製一下文字,這時候就要把手離開鍵盤到滑鼠或是觸控板上去點你要複製的文字,喔對你可能還要先找到你鼠標在哪,在 tmux 裡其實你可能可以完全不用滑鼠來複製文字,舉例來說,有個 用 git 繪製的捷運路線 repository:

$ git log --graph --oneline --decorate --all

...
| * | ca0b1f4 (tag: 中山國中) 中山國中
| | | * c13ea61 (HEAD -> orange-b, tag: 蘆洲, origin/orange-b) 蘆洲
| | | * 5bbbaab (tag: 三民高中) 三民高中
| | | * dc52586 (tag: 徐匯中學) 徐匯中學
...
* | | |   761cd5f (tag: 中山) 中山
|\ \ \ \
| |_|/ /
|/| | |
| * | | 91631c6 (tag: 北門) 北門
* | | |   e934518 (tag: 台北車站) 台北車站
|\ \ \ \
...

我想要 checkout 到 台北車站 ,我可以快速地

  1. Ctrl-v 進入 copy-mode
  2. hjkl, e, w, b 到達要選取的 sha (或是 台北車站 這幾個字,有時候 tag 也不短)
  3. v 開始選取
  4. e / w / b 選取
  5. y 複製
  6. q 離開 copy-mode
  7. 輸入 git checkout
  8. Ctrl-p 貼上

就得到

$ git checkout e934518

copy-mode-vi

tmux 複製多行也是沒問題的,所以也可以拿來複製大量複雜的文字,大概需要注意的就是 tmux 的剪貼簿是跟系統剪貼簿沒有任何關係的,只能在 tmux 中使用,網路上也有人提供打通的方法,不過因為如果是要貼在其他 GUI 應用程式,那使用滑鼠也是免不了的了,那就用滑鼠複製吧

tmux 最近幾個版本對 copy-mode 有不少的改變,可能要注意一下,我用的是 tmux -V; # => tmux 2.4

tmux 一些小知識

有哪些 keybindings?

可以用 <prefix> ? 列出目前的 keybindings ,而且這邊的格式就是設定檔的格式,對哪個不爽就複製下去貼到設定檔 ~/.tmux.conf 改就好,當然也請參考 tmux man page

如果有兩個使用者 attacth 同一個 session 會發生甚麼事?

完全不會掛掉!兩邊會完全同步,而且都可以~~輸入東西、操作~~互相干擾,甚至 client window 不一樣大也考慮到了:

multi user attacthed and as for keybindings

或許哪天投影機壞掉或是同學在遙遠的地方的地方還是可以用這種方式 “share” 螢幕做教學或是問問題呢,雖然不知道穩定性怎麼樣就是了XDD

感謝閱讀!

這段時間修過不少次設定檔,我也趁寫這篇文的機會把 ~/.tmux.conf 一些沒在用的東西刪掉,目前剩的應該就是我個人覺得實用的囉

以上是我個人使用 tmux 兩三年下來覺得不錯跟大家分享,希望能讓你對 tmux 有不同的了解!

OSX 透過 homebrew 安裝 tmux

brew install tmux

就這樣。