再也不用擔心 SSH 斷開了 - tmux 命令

Linux開發那些事兒發表於2020-11-02

在伺服器開發的過程中,經常使用SSH連線到遠端服務上執行指令碼,有些指令碼可能需要執行一段時間

在指令碼執行期間,如果會話超時或者會話意外斷開又或者不小心關掉了關掉了當前會話視窗,那麼指令碼有可能執行到一半兒時就被強制停止了

更麻煩的是,可能資料只修改了一部分,而另一部分又沒有修改,相當於出現髒資料了,這時就需要先恢復已經修改了的資料,才能再次執行指令碼

今天介紹的 tmux 命令可以完美的避免上述問題

tmux 簡介

tmux 是一個終端多路複用器,在終端中可以建立,訪問和控制多個終端會話

在一個會話中可以開啟多個視窗,每個視窗都佔據整個螢幕,一個視窗還可以分成多個窗格

tmux 讓遠端終端視窗和會話分離開了,終端視窗關閉時,會話繼續在後臺執行,新的終端視窗可以隨時接入會話,接入之後終端視窗上會顯示會話的資訊

tmux 啟動時,會預設建立一個具有單個視窗的會話,在會話螢幕的底部,顯示當前會話的資訊

Linux下 screen 命令的功能與 tmux 命令相似,相比 screen,tmux更易用,功能也更強大

安裝

tmux 一般都是需要自己安裝的,可以使用下面的命令安裝 tmux

sudo yum install tmux

基礎概念

在講 tmux 命令的使用之前,先解釋下 tmux中的 會話(session),視窗(window),窗格(pane) 之間的關係

一個遠端伺服器終端視窗可以管理多個tmux會話(session)

一個tmux會話裡可以管理多個視窗(window), 視窗(window)之間是互相獨立的, 並且可以切換到任一視窗

一個視窗(window)可以劃分成多個窗格(pane), 窗格之間是互相獨立的, 也可以切換到任一窗格

快捷鍵字首

進入tmux會話之後,會話中所有的快捷鍵,都需要先輸入 Ctrl + B組合鍵,後面再輸入快捷鍵才會生效,這裡的 Ctrl + B組合鍵就是快捷鍵的字首,可以把它理解成啟用快捷鍵的字首命令

進入tmux會話之後,tmux會話和終端分離的快捷命令是 Ctrl + B d

具體的使用方法是: 先在 tmux會話中,按下鍵盤上 Ctrl + B 組合鍵,然後再按下字母 d 鍵,會話就會和終端分離

會話操作

一個遠端終端視窗可以建立多個會話,會話之間相互獨立,可以隨時分離、接入、退出,轉換、重新命名會話

  • 新建會話

終端中輸入 tmux命令, 就進入了 tmux 視窗,底部是一個狀態列,狀態列左邊是會話ID、視窗ID,當前使用者命令目錄,狀態列右邊是系統資訊,具體的如下圖所示:

1:會話ID,預設從0開始,依次遞增

2:視窗ID,預設從0開始,依次遞增

3:當前使用者命令目錄

4:系統資訊

上面個的例子使用了ID編號來標識會話,實際使用中不便於記憶,也不直觀,可以使用 tmux new -s <session-name> 建立一個自定義名字的會話

[root@ecs-centos-7 ~]# tmux new -s aa
[root@ecs-centos-7 ~]# tmux ls
aa: 1 windows (created Sun Sep 20 23:26:33 2020) [134x34] (attached)

上面的例子中,tmux new -s aa 命令建立了一個名字是aa的會話

tmux ls命令是檢視系統中的所有會話,從命令輸出結果中可以看到

會話的名字是aa, 會話共有1個視窗,會話建立時間是Sun Sep 20 23:26:33 2020,後面的 attached 字串表示當前終端已經接入了名字為aa的會話

  • 分離會話

在 tmux視窗中輸入 tmux detach 命令或者使用快捷鍵 Ctrl + B d,即先按下 Ctrl + B鍵,再按下d 鍵,就會和會話分離

[root@ecs-centos-7 ~]# tmux detach
[aa] 0:root@ecs-centos-7:~*
[detached]
[root@ecs-centos-7 ~]#

上面的例子中,輸入 tmux detach 命令之後tmux視窗從名字為 aa 的會話中分離出來了

  • 接入會話

tmux視窗中,使用 tmux attach -t 會話名或者會話ID 接入到指定會話名字或者會話ID的會話中

[root@ecs-centos-7 ~]# tmux ls
aa: 1 windows (created Sun Sep 20 23:26:33 2020) [134x34]
bb: 1 windows (created Mon Sep 21 22:51:01 2020) [134x34]

[root@ecs-centos-7 ~]# tmux attach -t bb

[bb] 0:root@ecs-centos-7:~* 

上面的例子中 tmux ls 命令列出所有的會話,從結果中可以看到,目前有會話名字為 aabb 兩個會話,tmux attach -t bb 命令使tmux視窗接入會話bb

  • 轉換會話

有時tmux視窗已經接入了一個會話,想轉到另一個會話中執行命令,可以使用 tmux switch -t 會話名字或者會話ID 轉換到指定會話名字或者會話ID的會話中

[root@ecs-centos-7 ~]# tmux ls
aa: 1 windows (created Sun Sep 20 23:26:33 2020) [134x34]
bb: 1 windows (created Mon Sep 21 22:51:01 2020) [134x34] (attached)

[root@ecs-centos-7 ~]# tmux switch -t aa
[root@ecs-centos-7 ~]# tmux ls
aa: 1 windows (created Sun Sep 20 23:26:33 2020) [134x34] (attached)
bb: 1 windows (created Mon Sep 21 22:51:01 2020) [134x34] 

上面的例子中tmux視窗剛開始是接入的是 bb 的會話, 執行 tmux switch -t aa, 通過 tmux ls 命令結果可以知道tmux視窗從 bb 會話轉換到 aa 會話中了

  • 重新命名會話

在實際使用 tmux的過程中,為了便於記憶以及識別,會話名字都會改成一個有意義並且容易記憶的名字,tmux rename -t 舊會話名或會話ID 新會話名或會話ID 命令可以重新命名一個會話

Ctrl + B $ 快捷鍵之後,tmux視窗底部的狀態列變成可輸入狀態,此時可以輸入新的會話名字再按Enter鍵確認修改也可完成會話的重命令

[root@ecs-centos-7 ~]# tmux ls
aa: 1 windows (created Sun Sep 20 23:26:33 2020) [134x34]
bb: 1 windows (created Mon Sep 21 22:51:01 2020) [134x34]
[root@ecs-centos-7 ~]# tmux rename -t aa dev
[root@ecs-centos-7 ~]# tmux rename -t bb test
[root@ecs-centos-7 ~]# tmux ls
dev: 1 windows (created Sun Sep 20 23:26:33 2020) [134x34]
test: 1 windows (created Mon Sep 21 22:51:01 2020) [134x34]

上面的例子中,把 會話名aa 修改成 dev 表示這個會話是用於執行開發任務,把會話名 bb 修改成 test 表示這個會話是用於測試任務

  • 退出會話

當會話中任務執行完成之後,為了不在佔用系統資源,可以在會話中輸入 exit 命令或者 tmux kill-session -t 會話名或會話ID 命令 退出當前會話

如果tmux視窗沒有接入任何一個會話中,tmux kill-seesion -t 會話名或會話ID 命令會使指定會話名或會話ID退出會話,tmux kill-server 命令使所有會話全部退出

[root@ecs-centos-7 ~]# tmux ls
aa: 2 windows (created Mon Sep 21 23:45:36 2020) [134x34]
bb: 1 windows (created Mon Sep 21 23:56:35 2020) [134x34]
cc: 1 windows (created Mon Sep 21 23:56:59 2020) [134x34]
dd: 1 windows (created Mon Sep 21 23:57:08 2020) [134x34]

[root@ecs-centos-7 ~]# tmux kill-session -t dd
[root@ecs-centos-7 ~]# tmux ls
aa: 2 windows (created Mon Sep 21 23:45:36 2020) [134x34]
bb: 1 windows (created Mon Sep 21 23:56:35 2020) [134x34]
cc: 1 windows (created Mon Sep 21 23:56:59 2020) [134x34]

[root@ecs-centos-7 ~]# tmux kill-server
[root@ecs-centos-7 ~]# tmux ls
failed to connect to server

上面例子中,一開始總共有 aabb, cc, dd 四個會話,tmux kill-session -t dd 命令使 dd 會話退出了,tmux kill-server 命令使剩下的 aa, bb, cc 會話也全部退出了

視窗操作

  • 建立視窗

tmux new-window命令用來建立一個視窗, 也可以使用快捷鍵 Ctrl + B c建立視窗

新建會話時,預設會建立一個視窗ID為0的視窗,每次建立視窗,視窗ID會自動遞增, 新視窗會自動變成活躍視窗

[root@ecs-centos-7 ~]# tmux list-window
0: root@ecs-centos-7:~* (1 panes) [134x34] [layout bb3e,134x34,0,0,1] @1 (active)

[root@ecs-centos-7 ~]# tmux new-window
[root@ecs-centos-7 ~]# tmux list-window
0: root@ecs-centos-7:~- (1 panes) [134x34] [layout bb3e,134x34,0,0,1] @1
1: root@ecs-centos-7:~* (1 panes) [134x34] [layout bb45,134x34,0,0,8] @8 (active)

上面例子中 tmux list-window 是列出當前會話中所有的視窗,它的結果中最左邊的數字是視窗ID,最右邊括號的字串 active 表示視窗是活躍狀態

會話只有一個視窗時,預設就是活躍狀態,使用 tmux new-window 命令建立一個視窗之後,預設新視窗是活躍狀態

  • 切換視窗

下面是切換視窗相關的快捷鍵,在按下面的快捷鍵之前,需要先按快捷鍵字首 ( 預設是 Ctrl + B )

p  前一個視窗
n  下一個視窗
l  最後一個視窗
w  選擇視窗

我們以 ==選擇視窗== 的快捷鍵為例,按 Ctrl + B w 鍵之後,會出現類似下面的視窗列表

(0)  0: root@ecs-centos-7:~- "ecs-centos-7.4-64bit-20200212"    
(1)  1: root@ecs-centos-7:~  "ecs-centos-7.4-64bit-20200212"    
(2)  2: root@ecs-centos-7:~  "ecs-centos-7.4-64bit-20200212"    
(3)  3: root@ecs-centos-7:~* "ecs-centos-7.4-64bit-20200212"

同時游標預設選中當前活躍的視窗,我們可以從列表中選擇一個視窗,然後按Enter鍵,就會切換到選中的視窗

  • 刪除視窗

tmux kill-window 命令可以刪除當前視窗,當會話只有一個視窗時,使用這個命令會自動結束會話

tmux kill-window -t 視窗ID 命令是刪除指定視窗ID的視窗

[root@ecs-centos-7 ~]# tmux list-window
0: root@ecs-centos-7:~  (1 panes) [171x42] [layout b4bd,171x42,0,0,0] @0
1: root@ecs-centos-7:~- (1 panes) [171x42] [layout b4be,171x42,0,0,1] @1
2: root@ecs-centos-7:~* (1 panes) [171x42] [layout b4bf,171x42,0,0,2] @2 (active)
[root@ecs-centos-7 ~]# tmux kill-window -t 0
[root@ecs-centos-7 ~]# tmux list-window
1: root@ecs-centos-7:~- (1 panes) [171x42] [layout b4be,171x42,0,0,1] @1
2: root@ecs-centos-7:~* (1 panes) [171x42] [layout b4bf,171x42,0,0,2] @2 (active) 

[root@ecs-centos-7 ~]# tmux kill-window
[root@ecs-centos-7 ~]# tmux list-window
1: root@ecs-centos-7:~* (1 panes) [171x42] [layout b4be,171x42,0,0,1] @1 (active)

上面的例子中,一開始有視窗ID分別是 0, 1, 2 的三個視窗,2 號 的視窗是活躍狀態

tmux kill-window -t 0 命令刪除了 0 號視窗, 活躍視窗不變,通過 tmux list-window 命令檢視視窗列表,此時還剩下 1, 2 號視窗

再執行 tmux kill-window 命令刪除當前活躍視窗,最後通過 tmux list-window 再次檢視視窗列表,會話只剩下 1 號視窗了,同時因為 2 號視窗刪除了,所以活躍視窗變成了1 號視窗了

窗格操作

  • 劃分窗格

tmux split-window 命令可以把視窗劃分成上下兩個窗格

tmux split-window -h 命令可以把視窗劃分成左右兩個窗格

上圖中,第一步執行 tmux split-window 命令把視窗劃分成上下兩個窗格,滑鼠游標預設在下面的窗格中,第二步執行 tmxu split-window -h 命令把下面的窗格劃分成左右兩個窗格,滑鼠游標預設在右邊的窗格中

  • 切換窗格

切換窗格可以看成滑鼠的移動,切換到目標窗格之後,滑鼠的游標也會移動到目標窗格中

tmux select-pane -U 命令可以切換到上一個窗格

tmux select-pane -D 命令可以切換到下一個窗格

tmux select-pane -L 命令可以切換到左邊窗格

tmux select-pane -R 命令可以切換到右邊窗格

Ctrl +B 方向鍵 快捷命令可以快速切換到上下左右窗格中,方向鍵是小鍵盤旁邊的上下左右方向鍵

  • 交換窗格

tmux swap-pane -U 命令使當前窗格和上面的窗格交換位置

tmux swap-pane -D 命令使當前窗格和下面的窗格交換位置

Ctrl + B { 快捷鍵是和上一個窗格交換位置

Ctrl + B } 快捷鍵是和下一個窗格交換位置

上面的例子中,先輸入 tmux split-window 命令把視窗劃分成上下兩個窗格,滑鼠游標在下面的窗格中,為了交換窗格操作前後的資料對比,在下面的窗格輸出一個測試字串

在下面的窗格中輸入 tmux swap-pane -U 命令,上下窗格互相交換了位置,滑鼠游標此時停留在上面的窗格中

在上面的窗格中輸入 tmux swap-pane -D 命令,上下窗格再次互相交換位置,滑鼠的游標變成了停留在下面的窗格中了

  • 刪除窗格

tmux kill-pane 命令可以刪除當前窗格,或者輸入 exit 命令也可以刪除當前窗格

tmux kill-pane -t 窗格ID 命令可以刪除指定ID的窗格

Ctrl + B x 快捷鍵可以刪除當前窗格,狀態列有一個是否刪除的二次確認

在上面的例子中,有上下兩個窗格,在下面的窗格中輸入 tmux kill-pane 命令,會刪除當前窗格,刪除之後,滑鼠游標自動移動到上面的窗格中

上面的窗格中輸入 tmux list-pane 命令是檢視當前的窗格列表,從結果可以看出,目前只剩下 0 號窗格

再次輸入 tmux kill-pane -t 0 命令,將 0 號窗格也刪除了,由於刪除的是會話最後一個窗格,所以刪除操作會導致會話也退出了

小結

上面所講述的只是 tmux 的一些日常用法,通過tmux list-command 命令可以瞭解更多命令的使用,通過 tmux list-keys 命令可以瞭解更多的快捷鍵的使用

相關文章