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

在服務器開發的過程中,經常使用 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 命令列出所有的會話,從結果中可以看到,目前有會話名字爲 aa 和 bb 兩個會話,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 窗口底部的狀態欄變成可輸入狀態,此時可以輸入新的會話名字再按回車鍵確認修改也可完成會話的重命令

[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

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

窗口操作

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"

同時光標默認選中當前活躍的窗口,我們可以從列表中選擇一個窗口,然後按回車鍵,就會切換到選中的窗口

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 命令可以瞭解更多的快捷鍵的使用

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/_OUoFGNIfSZrApKi2RPcFA