linux-tmux-terminal-multiplexer-tutorial-20191204-02.png

圖片來源: GT-Wang


tmux 是一款 terminal mutiplexer (終端機多工器),自帶切割畫面 (pane) 的功能而且能夠在背景執行。
這篇主要紀錄在公司 Border (跳板機) 手動編譯安裝 for single user
應用場景、操作,請參考這幾篇文章:

操作 1 ==> Linux tmux 終端機管理工具使用教學 - G. T. Wang
操作 2 (gif) ==> 終端機 session 管理神器 — tmux.| Larry・Blog
應用場景 ==> 你終究會用tmux的,那為何不一開始就學 (基礎篇)

因為不小心被 Upton 看到我在編譯 tmux (偷看人家,害羞 >///<) 就順便解釋 tmux 應用在公司環境有什麼優勢!
一般來說我們都是連進 BD 後直接 sudo ssh root@xxxx 連入目標機器執行指令,可是當 VPN 斷線發生時… 在目標機器執行的指令會因為 ssh session 中斷而被強制終止。

沒有 tmux 的情況:

1
office == (ssh) ==> BD == (ssh) ==> RD's VM
1
2
3
4
5
6
7
8
9
## in office XShell Desktop
[C:\~]$ ssh tesla_plaid@<BD_IP>

## login in BD
[tesla_plaid@BD_IT_Local-Test-110 ~]$ sudo ssh root@RDs VM

## login in RD's VM

[root@Web_Server] watch -n3 echo 'hi'

當 VPN 斷線,遠端執行的命令就會被 close 掉

1
office == (X) ==> BD == (X) ==> RD's VM

使用 tmux 的狀況:

1
office == (ssh) ==> BD | tmux == (ssh) ==> RD's VM

當 VPN 斷線,因為與 RD’s VM 的 ssh session 是被接在 tmux 身上,tmux 自帶背景執行因此在 RD’s VM 執行的命令並不會中斷。

1
office == (X) ==> BD | tmux == (O) ==> RD's VM

重播 VPN 之後只需要重新登入 BD,打開 tmux session 即可。
有點像是在 BD 放了一台筆電,用那台筆電去連 RD 的機器
我們 VPN 斷線,只是碰不到筆電,原本跑在筆電的工作不會斷線


安裝 tmux

主流 linux distribution 都能透過套件管理器直接安裝。

Ubuntu

1
apt install tmux -y

RHEL/CentOS

1
yum install tmux -y

MacOS 不是 Linux distro 不過 Unix like

1
brew install tmux

source code 編譯安裝到跳板機

tmux installing wiki

tmux 會使用到 libevent, ncurses 這兩個相依套件。
我已經把這次使用的打包到 Nextcloud 上 (SYS -> tmux_compile) 嫌去官網抓麻煩的可以直接下載回來丟到跳板機上

(小弟使用 WSL 透過 rsync 將檔案上傳至跳板機)

1
rsync -avP /home/xzk_wsl/download_c/Downloads/tmux_compile/ <username>@192.168.x.x:~/

自動編譯 + 安裝腳本

其中使用 gizp 的原因是直接使用 tar -zxvf 或者 tar -tvf (查看壓縮包內目錄) 都出現錯誤:

Extracting a tar.gz file returns, “This does not look like a tar archive.”

1
2
3
tar: This does not look like a tar archive
tar: Skipping to next header
tar: Exiting with failure status due to previous errors

執行完畢後直接下達 tmux 就可以使用了~

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
## install tmux for board VM


## un-tar.gz

tar -zxvf ~/libevent-2.1.12-stable.tar.gz
tar -zxvf ~/tmux-3.2.tar.gz

gzip -d ~/ncurses-6.2.tar.gz
tar -zxvf ~/ncurses-6.2.tar

## compile and install libevent

cd libevent-2.1.12-stable
./configure --prefix=$HOME/local --enable-shared
make && make install
cd ~

## compile and install ncurses

cd ncurses-6.2
./configure --prefix=$HOME/local --with-shared --with-termlib --enable-pc-files --with-pkg-config-libdir=$HOME/local/lib/pkgconfig
make && make install
cd ~

## compile and install tmux

cd tmux-3.2
PKG_CONFIG_PATH=$HOME/local/lib/pkgconfig ./configure --prefix=$HOME/local
make && make install

## export ENV_VAR

export PATH=$HOME/local/bin:$PATH
export LD_LIBRARY_PATH=$HOME/local/lib:$LD_LIBRARY_PATH
export MANPATH=$HOME/local/share/man:$MANPATH

常用指令

tmux shortcuts & cheatsheet

cheating sheet is here~

pane 基礎

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
%       垂直分割
"       水平分割
o       以輪流方式輪流切換 pane
arrow   切換目標
space   切換佈局


!       將當前 pane 變成獨立 window
x       關閉當前 pane
q       顯示 pane number
z       zoom-in 當前 pane (再按一次回來,狀態列會多一個 *z)

windows 基礎

1
2
3
4
5
6
c       建立新 windows (create)
&       關閉 windows
w       (大推) 視覺化選單
n       切換至下一個視窗 (next)
p       切換至上一個視窗 (previous)
number  切換至指定的 windows 視窗

session 基礎

1
2
3
$       重新命名目前的 session
d       detach 當前 session
s       以視覺方式切換 session

將 pane 合併到其它 window

Move a tmux pane from one window to another

Moving tmux pane to window

1
2
3
4
## -p <p_int> 可以省略,預設當下 pane number。
## -t <int> 目標 window number

:join-pane -s <p_int> -t <int>

調整 pane 大小

In tmux can I resize a pane to an absolute value

Resizing tmux panes

1
2
3
4
5
6
7
8
9
## 指定 cell size

:resize-pane -[DULR] <cells_number>

## shortcut 連續 (不過剛建立的水平分割好像不能用 QQ)
ctrl+arrow

## shortcut 單次 (這個水平分割就可以使用了)
Esc+arrow

平均分配

How do I equally balance tmux(1) split panes?

1
2
3
4
5
6
:select-layout even-vertical
:select-layout even-horizontal

## short cut 
Ctrl-b Alt-1
Ctrl-b Alt-2

不過通常我比較喜歡直接用 space 切換回來

重新排序 window

How do I reorder tmux windows?

1
2
## <int> 是目標 (target) 的意思
:swap-window -t <int>