到目前為止,我們已經(jīng)學(xué)習(xí)了日常使用 tmux 以及修改配置。而 tmux 最受開發(fā)人員歡迎的功能之一就是結(jié)對(duì)編程。那是我第一次使用 tmux,當(dāng)我的朋友向我介紹 tmux 的眾多功能時(shí)我立刻就喜歡上了這個(gè)功能。
結(jié)對(duì)編程有很多好處。和其他開發(fā)人員一起工作能夠幫你發(fā)現(xiàn)許多你無法自己看到的事情,除非你們身處同一位置,否則結(jié)對(duì)編程就會(huì)變得相當(dāng)困難。使用例如 iChat,Skype 甚至是 GoToMeeting 這種屏幕共享的軟件會(huì)占用相當(dāng)多的帶寬,而且在網(wǎng)絡(luò)狀況不好時(shí)就會(huì)變得非常糟糕。在本章,我們會(huì)學(xué)習(xí)使用 tmux 進(jìn)行結(jié)對(duì)編程,之后你就可以和另一位開發(fā)人員一起遠(yuǎn)程工作了,甚至可以使用糟糕的賓館 WiFi 網(wǎng)絡(luò)。
和遠(yuǎn)程用戶協(xié)作有兩種方式。第一種方式需要?jiǎng)?chuàng)建一個(gè)新的用戶賬戶,你和他人一起共享這個(gè)賬戶。在這個(gè)賬戶下配置 tmux 和開發(fā)環(huán)境,然后把它作為一個(gè)共享的工作空間。第二種辦法是使用 tmux 的 sockets 連接,這樣你就可以讓第二個(gè)用戶連接到你的 tmux 會(huì)話中而無需共享你的賬戶信息。
這兩種方法都有一種固有的安全缺陷:它們能讓他人看到你的屏幕信息和你的賬戶。你可能在放任某人任意查看你的文件。要解決這個(gè)問題,最好使用一個(gè)中間服務(wù)器來進(jìn)行結(jié)對(duì)編程。使用一個(gè)便宜的 VPS 或是一個(gè)用 VirtualBox(鏈接)或 Vagrant(鏈接)創(chuàng)建的虛擬機(jī),你可以快速地創(chuàng)建一個(gè)用于結(jié)對(duì)編程的開發(fā)環(huán)境。在本章,我們會(huì)學(xué)習(xí)在遠(yuǎn)程服務(wù)器上分別使用這兩種進(jìn)行結(jié)對(duì)編程。
使用共享賬戶是和他人共同協(xié)作的最簡(jiǎn)便的方式。在一個(gè) nutshell 里,你可以開啟機(jī)器上的 SSH 訪問權(quán)限,將它作為主機(jī),然后在機(jī)器上安裝并配置 tmux,之后再創(chuàng)建一個(gè) tmux 會(huì)話。第二個(gè)用戶可以使用相同的賬戶登錄到這臺(tái)機(jī)器里然后連接到剛才創(chuàng)建的 tmux 會(huì)話中。通過使用 SSH 公開密鑰,可以讓登錄過程變得透明化。下面我們來討論這個(gè)過程。假設(shè)我們?cè)谑褂靡慌_(tái)名為 puzzles 的服務(wù)器,它使用 Ubuntu 操作系統(tǒng)并且已經(jīng)安裝了 SSH 后臺(tái)程序。
首先,在服務(wù)器上創(chuàng)建一個(gè)名為 tmux 的用戶賬戶。這個(gè)賬戶專門用于結(jié)對(duì)操作。
tmux@puzzles$ adduser tmux
使用新創(chuàng)建的賬戶前,需要配置這個(gè)賬戶讓它添加其他開發(fā)人員的 SSH 密鑰,這樣他們就可以通過這些密鑰來登錄這個(gè)賬戶??梢栽?tmux 賬戶下創(chuàng)建 ~/.ssh/authorized_keys
文件來完成這個(gè)操作。首先使用 su
命令切換到 tmux 賬戶:
tmux@puzzles$ su tmux
然后要?jiǎng)?chuàng)建 .ssh
目錄和 .ssh/authorized_keys
文件,并為它們配置相應(yīng)的文件權(quán)限。確保只有 tmux 這個(gè)用戶可以讀、寫或執(zhí)行這些文件。命令如下:
tmux@puzzles$ mkdir ~/.ssh
tmux@puzzles$ touch ~/.ssh/authorized_keys
tmux@puzzles$ chmod 700 ~/.ssh
tmux@puzzles$ chmod 600 ~/.ssh/authorized_keys
接下來,就可以把公鑰傳輸?shù)竭@臺(tái)服務(wù)器上了。在桌面工作機(jī)上,生成本機(jī)的公鑰然后上傳到服務(wù)器:
$ scp -p id_rsa.pub tmux@puzzles.local
然后在服務(wù)器上,把公鑰添加到 authorized_keys
里。
tmux@puzzles$ cat id_rsa.pub >> ~/.ssh/authorized_keys
其他需要這個(gè)共享賬戶登錄到服務(wù)器上的所有人都要重復(fù)上述過程。
從這里開始,我們來配置 tmux,文本編輯器,編譯器,編程需要和版本控制系統(tǒng),就像在其他開發(fā)環(huán)境要做的那樣。然后在服務(wù)器上創(chuàng)建一個(gè)新的 tmux 會(huì)話。
tmux@puzzles$ tmux new-session -s Pairing
團(tuán)隊(duì)中的其他成員可以登錄到服務(wù)器上然后通過以下命令連接到這個(gè)會(huì)話中:
tmux@puzzles$ tmux attach -t Pairing
然后就可以在同一個(gè)項(xiàng)目里共同協(xié)作了。當(dāng)然,我們可以從會(huì)話中分離出來在后來再重新連接到這個(gè)會(huì)話,也就是說可以讓開發(fā)環(huán)境一次就運(yùn)行數(shù)天甚至數(shù)周。這樣只要有一個(gè)支持 SSH 的終端就可以在任何時(shí)間、任何地點(diǎn)都能連接到這個(gè)開發(fā)環(huán)境了。
當(dāng)兩個(gè)人連接到同一個(gè) tmux 會(huì)話時(shí),他們通常會(huì)看到相同的內(nèi)容并在同一個(gè)窗口里交互。但是很多時(shí)候人們希望能夠在獨(dú)立的、不同的窗口工作而不用被完全控制。
使用“組會(huì)話(grouped session)”可以實(shí)現(xiàn)這個(gè)功能。下面我們來演示一下,首先先在遠(yuǎn)程服務(wù)器上創(chuàng)建一個(gè)新的會(huì)話叫做 groupedsession。
tmux@puzzles$ tmux new-session -s groupedsession
然后,另一個(gè)用戶不去連接到這個(gè)會(huì)話,而是通過“創(chuàng)建一個(gè)新的會(huì)話”來加入到這個(gè)會(huì)話里,他需要指定原始會(huì)話 groupedsession,然后再指定一個(gè)他或她自己的會(huì)話名,就像這樣:
tmux@puzzles$ tmux new-session -t groupedsession -s mysession
當(dāng)?shù)诙€(gè)會(huì)話啟動(dòng)時(shí),兩個(gè)用戶都可以同時(shí)在這個(gè)會(huì)話里進(jìn)行交互,就像是第二個(gè)用戶已經(jīng)連接到這個(gè)會(huì)話一樣。但是,每個(gè)用戶可以創(chuàng)建相互獨(dú)立的窗口。因此,如果新用戶創(chuàng)建了一個(gè)窗口,都會(huì)在狀態(tài)欄里看到新的窗口出現(xiàn)了,但是用戶仍然會(huì)處于當(dāng)前工作的窗口!這對(duì)那些“嘿,我有個(gè)想法我先去試試”的時(shí)刻特別適合,或者有時(shí)候有人想用 Emacs 而有人想用 Vim 的時(shí)候也很合適,就像圖13(兩個(gè)用戶共享同一個(gè)會(huì)話)所示的那樣。
圖13 - 兩個(gè)用戶共享同一個(gè)會(huì)話
第二個(gè)用戶可以使用 kill-session
命令殺死他或她的會(huì)話,而原始會(huì)話依然會(huì)存在。但是,如果所有的窗口都關(guān)閉的話那么這兩個(gè)會(huì)話都會(huì)被殺死。
使用共享賬戶和 tmux 是結(jié)對(duì)編程最簡(jiǎn)單的方式,但是有時(shí)候我們并不是總是愿意和團(tuán)隊(duì)成員共享賬號(hào)。下面我們來看看另一種方式。
使用 tmux 提供的 socket 支持,可以創(chuàng)建讓多個(gè)用戶非常容易連接的 tmux 會(huì)話。
首先,我們創(chuàng)建兩個(gè)新的用戶賬號(hào):一個(gè)名為 ted,另一個(gè)名為 barney。
tmux@puzzles$ sudo adduser ted
tmux@puzzles$ sudo adduser barney
接下來,創(chuàng)建“tmux”分組以及 /var/tmux
文件夾用來保存共享會(huì)話。
tmux@puzzles$ sudo addgroup tmux
tmux@puzzles$ sudo mkdir /var/tmux
要更改 /var/tmux
目錄的組權(quán)限,這樣 tmux 組就能訪問它了:
tmux@puzzles$ sudo chgrp tmux /var/tmux
然后修改文件夾的權(quán)限讓新的文件都能被所有的 tmux 組內(nèi)用戶訪問:
tmux@puzzles$ sudo chmod g+ws /var/tmux
最后,添加 Ted 和 Barney 用戶到 tmux 組內(nèi)。
tmux@puzzles$ sudo usermod -aG tmux ted
tmux@puzzles$ sudo usermod -aG tmux barney
之前,我們已經(jīng)使用過 new-session
命令來創(chuàng)建會(huì)話,但是那會(huì)使用默認(rèn)的 socket 位置,我們是無法對(duì)它進(jìn)行操作的。因此我們?cè)谶@里不會(huì)創(chuàng)建命名會(huì)話,而是通過 -S
參數(shù)來創(chuàng)建我們自己的會(huì)話。
我們先登錄 ted 賬戶然后使用 socket 創(chuàng)建一個(gè)新的 tmux 會(huì)話:
ted@puzzles$ tmux -S /var/tmux/pairing
在另一個(gè)終端窗口里,可以登錄 barney 然后連接到這個(gè)會(huì)話。連接時(shí)不必指定會(huì)話名,我們需要做的就是指定 socket 連接和 socket 文件的位置,就像這樣:
barney@puzzles$ tmux -S /var/tmux/pairing attach
barney 用戶現(xiàn)在已經(jīng)連接到 tmux 會(huì)話而且他看到的就是 ted 用戶所看到的內(nèi)容。
需要注意的一點(diǎn)是,使用這種方法來使用 tmux 時(shí),.tmux.conf
文件使用的配置是第一個(gè)啟動(dòng)這個(gè)會(huì)話的用戶的配置。使用兩個(gè)獨(dú)立的賬戶并不意味著每個(gè)賬戶都可以在 tmux 會(huì)話里使用各自的配置文件,而是說他們可以根據(jù)其他的目的來定制他們的賬戶,然后在需要時(shí)都可以初始化他們所獨(dú)有的 tmux 會(huì)話。
現(xiàn)在你已經(jīng)學(xué)會(huì)了如何通過 tmux 與他人分享屏幕,你可以使用它來進(jìn)行遠(yuǎn)程訓(xùn)練、在開源項(xiàng)目上進(jìn)行即興合作,或者是遠(yuǎn)程演示。
另外,還可以使用這個(gè)技術(shù)在你的生產(chǎn)服務(wù)器上開啟 tmux 會(huì)話,加載監(jiān)測(cè)工具或者控制臺(tái),然后從會(huì)話分離出來,讓這些工具一直在后臺(tái)運(yùn)行。然后可以在你的機(jī)器上連接到這個(gè)會(huì)話,所有的一切都如你斷開連接時(shí)那樣。我曾經(jīng)在我的開發(fā)環(huán)境上就做過類似的事情。我在一個(gè) VPS 上配置了 tmux,然后在家里使用一臺(tái) iPad,一個(gè) SSH 客戶端以及一個(gè)藍(lán)牙鍵盤就可以寫代碼了。即便是在 3G 網(wǎng)絡(luò)下這樣做依然很流暢。
結(jié)對(duì)編程和遠(yuǎn)程協(xié)作只是 tmux 應(yīng)用在工作時(shí)提高工作效率的兩個(gè)例子。在下一個(gè)章節(jié),我們會(huì)學(xué)習(xí)在使用 tmux 窗口、面板和系統(tǒng)時(shí)其他更加高級(jí)的功能。
命令 | 描述 |
---|---|
tmux -S [socket] |
使用 socket 創(chuàng)建一個(gè)新的會(huì)話 |
tmux -S [socket] attach |
連接到一個(gè)已有的 socket 會(huì)話 |
tmux new-session -t [existing session] -s [new session] |
創(chuàng)建一個(gè)到組會(huì)話的連接 |
更多建議: