Try   HackMD

配合腳本快速建立 tmux 工作區

tags: linux, tmux, script, bash

tmux 的全稱是 Terminal Multiplexer,直譯過來就是終端(Terminal)多工器(Multiplexer),這個工具可以在單一 screen 之下 create, attach, detach 多個終端,熟悉之後十分好用。
只是和 vim,vi 系列相同,所有操作皆能且只能使用鍵盤,不像 GNOME Terminal 一樣有直觀的 GUI 介面,算不上友善的學習曲線使人又愛又恨。
關於 tmux 的基本概念和入門組合鍵,G. T. Wang 的文章提供了很不錯的繁體中文資料,本篇的重點在於如何配合 shell script 和 tmux 來快速建立一個順手的工作區。


  you can do this

keyword: tmux,script


自動化建立 tmux 工作區

建立腳本

首先,當然是創建一份腳本,第一行請記得加上 shebang

#!/bin/bash

這行會告知系統,接下來的部分是一份 bash script。


建立新的 session

接下來就可以開始建立一個新的 session,為了往後修改上的便利,可以使用一個變數來記錄 session 的名稱。

SESSION="S_NAME"

tmux new-session -d -s $SESSION

其中-d代表 detach,-s後面接 session 的名稱。

因為使用了-d,此時結果並不會顯示在螢幕上,有興趣的話可以使用

tmux attach -t "S_NAME"

來進入 tmux 檢查結果,之後再按 ctrl + b -> d 就可以再次 detach 回到原終端了。


  建立名為 S_NAME 的 session


window 重命名

剛建立的 session 會包含一個 window,同樣地我們也可以對該 window 命名以提高辨識度。

tmux rename-window -t $SESSION_NAME:0 'Main'

-t後需要提供目標 session 和 window,由於 session 是剛建立起來的,裡面唯一一個 window 的編號必為 0。最後的是新的命名Main

同樣地,有興趣檢查結果可以使用

tmux attach -t "S_NAME"

來進入 tmux 查看,然後使用 ctrl + b -> d 再次 detach 回到原終端。往後不再贅述。


  重命名 window 為 Main


傳送鍵盤指令

當然只創建 window 的話意義是不大的,tmux 也提供傳送鍵盤指令的功能,可以用於移動工作目錄,自動執行預設指令,啟動其他腳本等等。

例如:

tmux send-keys -t $SESSION:Main 'ping 8.8.8.8' C-m

則是等同輸入ping 8.8.8.8, 再按Enter。同樣地-t後接上目標 session 和 window。


  自動執行 ping 指令


分割 pane

在創建新的 window 前,我們可以先從當前 window 中分割出 pane。

tmux split-window -h -p 40 -t $SESSION:Main
tmux split-window -v -p 20 -t $SESSION:Main

其中-h代表水平 (horizontal),-v代表垂直 (vertical)。 -p後面接比例,例如-p 30就代表分割得到的新 pane 佔 30% 空間。垂直分割時新的是下方的 pane,水平分割時新的是右方的 pane。
-t則始終如一,用於指定 session 和 window。


  pane 分割示例

在分割的同時,當前的工作 pane 就會移到新的 pane 上,因此在執行水平分割之後,

tmux split-window -h -p 40 -t $SESSION:Main

當前 pane 就變更為右方(上)的 pane 了。這時候再執行垂直分割,

tmux split-window -v -p 20 -t $SESSION:Main

就會得到右下的 pane。


pane 選取

那如果有需要對同一個 pane 進行多次的切割呢?或者有工作需要再回到之前的 pane 執行呢?一般使用 tmux 時可以用 ctrl + b -> 方向鍵來選取 pane,使用命令也是同樣的道理。

tmux select-pane -t $SESSION:Main -L

其中-L代表往左,而上下左右則分別是-U-DLR -t依然是指定 session 和 window。

還記得之前啟動的ping指令嗎,現在來把他停下來吧。在上一條指令選取了左方 pane 後,我們可以再接上以下的指令

tmux send-keys -t $SESSION:Main C-c 'clear' C-m

這等於按下crtl^c,鍵入clear,再按Enter


  選取左方 pane 並清空其畫面


創建 window

單一 window 環境暫時告一段落,接下來就創建新的 window 吧。

tmux new-window -t $SESSION:1 -n 'star_war'

注意: 這邊的-t指定的是 session 和新的 window 編號。
-n用於指定新的 window 名稱。和創建 pane 時同樣,需要注意當前的工作 window 也會切換到新的 window 上。

至於為甚麼要把新的 window 命名為 starwar?因為 terminal 可以用來播放 starwar 啊!

tmux send-keys -t $SESSION:star_war 'telnet towel.blinkenlights.nl' C-m

連線到以上的 server,terminal 就會自動播放 star war 了,神奇吧!


  建立新的 window 並開始播放 star war


window 選取

和 pane 一樣,一般使用 tmux 時可以透過 ctrl + b -> n 來選取下一個 window,使用命令也可以達到同樣的目的。

tmux next -t $SESSION
tmux prev -t $SESSION
tmux next -t $SESSION

-t用於指定 session,next代表下一個 window,prev則是前一個 window。


  回到上一個 window

如果需要直接指定一個特定 window 的話,也可以使用 select-window

tmux select-window -t $SESSION:Main

同樣是在-t後指定 session 和 window。


attach 終端

做完了想做的設定後就可以 attach 回去看結果啦,跟一直在用的一樣,直接

tmux attach -t "S_NAME"

或者在腳本內的話

tmux attach -t $SESSION

也可以。

想要指定 attach 回去的 window 的話也可以指定 window 名稱或編號,反正我們每個 windows 都有好好地命名,那就當然是指定名稱比較好識別啦。

tmux attach -t $SESSION:star_war


  attach 回到 star war 播放頁


總結

以下就是建立一開始的範例圖的 tmux 的腳本(trust me, its simple)。

#!/bin/bash

SESSION="tmux_setup"

SESEXS=$(tmux ls | grep $SESSION)

if [ "$SESEXS" = "" ]
then
    tmux new-session -d -s $SESSION -x "$(tput cols)" -y "$(tput lines)"
    tmux rename-window -t $SESSION:0 'Main'
    tmux send-keys -t $SESSION:Main 'man man' C-m

    tmux split-window -v -p 40 -t $SESSION:Main
    tmux send-keys -t $SESSION:Main 'htop' C-m
    tmux select-pane -U

    tmux split-window -h -p 30 -t $SESSION:Main
    tmux send-keys -t $SESSION:Main 'genact' C-m
    tmux select-pane -D

    tmux split-window -h -p 60 -t $SESSION:Main
    tmux send-keys -t $SESSION:Main 'telnet towel.blinkenlights.nl' C-m

    tmux split-window -h -p 33 -t $SESSION:Main
    tmux send-keys -t $SESSION:Main 'tty-clock' C-m

    tmux split-window -v -p 50 -t $SESSION:Main
    tmux send-keys -t $SESSION:Main 'cmatrix' C-m


    tmux new-window -t $SESSION:1 -n 'bs1'
fi
tmux attach -t $SESSION:Main


疑難雜症

tmux window 自動重命名

甚麼?你用了rename-window可是 tmux 根本沒反應?或者操作一下又自動回到預設的命名?那你來對地方了。

首先在家目錄創建一個設定檔(設定檔不存在的話就直接建新的)

vim ~/.tmux.conf

在最後一行加上

set-option -g allow-rename off

然後讓 tmux 重新讀取一下

tmux source-file ~/.tmux.conf

搞定~

來源:神奇的 stackoverflow ,感謝 Mohammad Rajabloo。


pane 分割比例不如預期

明明是寫split-window -p 50,結果分割出來只剩個 20% 的空間?可能是 tmux 在 attach 的時候接到了新的視窗大小喔。

在創建新 session 時就先提供好終端資訊吧!

tmux new-session -d -s $SESSION -x "$(tput cols)" -y "$(tput lines)"

來源:stackexchange,感謝 Kamil Maciorowski。


參考資料

Scripting A Tmux Work-space Start-up

man tmux