# 配合腳本快速建立 tmux 工作區 ###### tags: `linux`, `tmux`, `script`, `bash` tmux 的全稱是 Terminal Multiplexer,直譯過來就是終端(Terminal)多工器(Multiplexer),這個工具可以在單一 screen 之下 create, attach, detach 多個終端,熟悉之後十分好用。 只是和 vim,vi 系列相同,所有操作皆能且只能使用鍵盤,不像 GNOME Terminal 一樣有直觀的 GUI 介面,算不上友善的學習曲線使人又愛又恨。 關於 tmux 的基本概念和入門組合鍵,[G. T. Wang 的文章](https://blog.gtwang.org/linux/linux-tmux-terminal-multiplexer-tutorial/)提供了很不錯的繁體中文資料,本篇的重點在於如何配合 shell script 和 tmux 來快速建立一個順手的工作區。 ![](https://i.imgur.com/giag5RK.png)   ***you can do this*** keyword: ```tmux```,```script``` [toc] --- ## 自動化建立 tmux 工作區 ### 建立腳本 首先,當然是創建一份腳本,第一行請記得加上 [shebang](https://zh.wikipedia.org/wiki/Shebang)。 ``` #!/bin/bash ``` 這行會告知系統,接下來的部分是一份 [bash](https://zh.wikipedia.org/wiki/Bash) script。 --- ### 建立新的 session 接下來就可以開始建立一個新的 session,為了往後修改上的便利,可以使用一個變數來記錄 session 的名稱。 ```=bash SESSION="S_NAME" tmux new-session -d -s $SESSION ``` 其中```-d```代表 detach,```-s```後面接 session 的名稱。 因為使用了```-d```,此時結果並不會顯示在螢幕上,有興趣的話可以使用 ```=bash tmux attach -t "S_NAME" ``` 來進入 tmux 檢查結果,之後再按 ctrl + b -> d 就可以再次 detach 回到原終端了。 ![](https://i.imgur.com/GKdD0dK.png)   ***建立名為 S_NAME 的 session*** --- ### window 重命名 剛建立的 session 會包含一個 window,同樣地我們也可以對該 window 命名以提高辨識度。 ```=bash tmux rename-window -t $SESSION_NAME:0 'Main' ``` ```-t```後需要提供目標 session 和 window,由於 session 是剛建立起來的,裡面唯一一個 window 的編號必為 0。最後的是新的命名```Main```。 同樣地,有興趣檢查結果可以使用 ```=bash tmux attach -t "S_NAME" ``` 來進入 tmux 查看,然後使用 ctrl + b -> d 再次 detach 回到原終端。往後不再贅述。 ![](https://i.imgur.com/b92MMz8.png)   ***重命名 window 為 Main*** --- ### 傳送鍵盤指令 當然只創建 window 的話意義是不大的,tmux 也提供傳送鍵盤指令的功能,可以用於移動工作目錄,自動執行預設指令,啟動其他腳本等等。 例如: ```=bash tmux send-keys -t $SESSION:Main 'ping 8.8.8.8' C-m ``` 則是等同輸入`ping 8.8.8.8`, 再按```Enter```。同樣地```-t```後接上目標 session 和 window。 ![](https://i.imgur.com/xedGbGU.png)   ***自動執行 ping 指令*** --- ### 分割 pane 在創建新的 window 前,我們可以先從當前 window 中分割出 pane。 ```=bash 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。 ![](https://i.imgur.com/cL7BMlS.png)   ***pane 分割示例*** 在分割的同時,當前的工作 pane 就會移到新的 pane 上,因此在執行水平分割之後, ```=bash tmux split-window -h -p 40 -t $SESSION:Main ``` 當前 pane 就變更為右方(上)的 pane 了。這時候再執行垂直分割, ```=bash tmux split-window -v -p 20 -t $SESSION:Main ``` 就會得到右下的 pane。 --- ### pane 選取 那如果有需要對同一個 pane 進行多次的切割呢?或者有工作需要再回到之前的 pane 執行呢?一般使用 tmux 時可以用 ctrl + b -> 方向鍵來選取 pane,使用命令也是同樣的道理。 ```=bash tmux select-pane -t $SESSION:Main -L ``` 其中```-L```代表往左,而上下左右則分別是```-U```,```-D```,```L```,```R```。 而```-t```依然是指定 session 和 window。 還記得之前啟動的```ping```指令嗎,現在來把他停下來吧。在上一條指令選取了左方 pane 後,我們可以再接上以下的指令 ```=bash tmux send-keys -t $SESSION:Main C-c 'clear' C-m ``` 這等於按下```crtl^c```,鍵入```clear```,再按```Enter``` ![](https://i.imgur.com/GRCTLtD.png)   ***選取左方 pane 並清空其畫面*** --- ### 創建 window 單一 window 環境暫時告一段落,接下來就創建新的 window 吧。 ```=bash tmux new-window -t $SESSION:1 -n 'star_war' ``` ***注意:*** 這邊的```-t```指定的是 session 和***新的*** window 編號。 ```-n```用於指定新的 window 名稱。和創建 pane 時同樣,需要注意當前的工作 window 也會切換到新的 window 上。 至於為甚麼要把新的 window 命名為 starwar?因為 terminal 可以用來播放 starwar 啊! ```=bash tmux send-keys -t $SESSION:star_war 'telnet towel.blinkenlights.nl' C-m ``` 連線到以上的 server,terminal 就會自動播放 star war 了,神奇吧! ![](https://i.imgur.com/FrHNsbv.png)   ***建立新的 window 並開始播放 star war*** --- ### window 選取 和 pane 一樣,一般使用 tmux 時可以透過 ctrl + b -> n 來選取下一個 window,使用命令也可以達到同樣的目的。 ```=bash tmux next -t $SESSION tmux prev -t $SESSION tmux next -t $SESSION ``` ```-t```用於指定 session,```next```代表下一個 window,```prev```則是前一個 window。 ![](https://i.imgur.com/clJt3LE.png)   ***回到上一個 window*** 如果需要直接指定一個特定 window 的話,也可以使用 ```select-window``` ```=bash tmux select-window -t $SESSION:Main ``` 同樣是在```-t```後指定 session 和 window。 --- ### attach 終端 做完了想做的設定後就可以 attach 回去看結果啦,跟一直在用的一樣,直接 ```=bash tmux attach -t "S_NAME" ``` 或者在腳本內的話 ```=bash tmux attach -t $SESSION ``` 也可以。 想要指定 attach 回去的 window 的話也可以指定 window 名稱或編號,反正我們每個 windows 都有好好地命名,那就當然是指定名稱比較好識別啦。 ```=bash tmux attach -t $SESSION:star_war ``` ![](https://i.imgur.com/NbhCxd3.png)   ***attach 回到 star war 播放頁*** --- ### 總結 以下就是建立一開始的範例圖的 tmux 的腳本(trust me, its simple)。 ```=bash #!/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 根本沒反應?或者操作一下又自動回到預設的命名?那你來對地方了。 首先在家目錄創建一個設定檔(設定檔不存在的話就直接建新的) ```=bash vim ~/.tmux.conf ``` 在最後一行加上 ```=bash set-option -g allow-rename off ``` 然後讓 tmux 重新讀取一下 ```=bash tmux source-file ~/.tmux.conf ``` 搞定~ 來源:神奇的 [stackoverflow](https://stackoverflow.com/questions/6041178/keep-the-windows-name-fixed-in-tmux) ,感謝 Mohammad Rajabloo。 --- #### pane 分割比例不如預期 明明是寫```split-window -p 50```,結果分割出來只剩個 20% 的空間?可能是 tmux 在 attach 的時候接到了新的視窗大小喔。 在創建新 session 時就先提供好終端資訊吧! ```=bash tmux new-session -d -s $SESSION -x "$(tput cols)" -y "$(tput lines)" ``` 來源:[stack....exchange](https://unix.stackexchange.com/questions/569729/tmux-not-splitting-panes-with-desired-percentage-size),感謝 Kamil Maciorowski。 --- ### 參考資料 [Scripting A Tmux Work-space Start-up ](http://ryan.himmelwright.net/post/scripting-tmux-workspaces/) [man tmux](https://man7.org/linux/man-pages/man1/tmux.1.html)