原文鏈接:https://fuckcloudnative.io/posts/iterm2-auto-login/
對于 YAML 工程師來說,我們經常需要 ssh 登錄不同的服務器,每次登錄時都要經歷兩個步驟:
- 輸入
ssh root@host-ip - 輸入密碼
每次都重復這樣的操作,不僅麻煩,還要記憶好多東西,對于 Windows 用戶來說,可以使用 Xshell 來實作自動登錄功能,macOS 用戶就比較麻煩了,iTerm2 是 macOS 平臺上最強大的終端工具,雖然默認沒有提供自動登錄的功能,但我們可以嘗試通過它提供的其他功能來打造自動登錄的功能,
當然,既然我寫了這篇文章,就說明我已經找到了方法,下面就直接開門見山放干貨,我想提醒你的是,我這里提供的方法絕對是你從來沒有見過的,你可能會覺得網上能搜到很多和我類似的方案,但如果你仔細看就能看出區別來,網上的方案都是不完美的,和其他功能同時使用時會出現莫名其妙的問題(具體是什么問題后面我會講到),我把這些問題都解決了,得到了一個極其完美的方案,
本文將提供兩種自動登錄方案,首先來看第一種方案,
1. 通過觸發器自動登錄
iTerm2 有一個非常強大的功能叫觸發器(Trigger),觸發器是用戶可配置的正則運算式,當終端會話接收到與正則運算式相匹配的文本時,會執行相關的操作,這里的操作包括突出顯示匹配的文本,顯示警報,發回文本等等,
觸發器的一種高級用法是捕獲與正則運算式匹配的輸出,并在工具列中顯示這些匹配線, 例如,您可以創建一個匹配編譯器錯誤的觸發器, 當你運行時,錯誤會出現在你的視窗一側,你可以點擊每一個跳到它的右邊, 更多資訊可在 Captured Output 手冊中找到,
本文將利用觸發器來實作 ssh 自動登錄的功能,首先點擊 Preference -> Profiles,選中你要登錄的服務器,Command 這里填寫你的 ssh 登錄的 ip 和用戶名,如果埠不是 22 還要指定埠:

然后點擊 Advanced,找到 Trriggers,點擊 edit:

在 Regular Eexpression 中,填寫你要匹配的正則運算式,由于這里是要在看到 password 的提示后輸入密碼,所以這里填寫 password,如果你服務器的密碼提示是 passwd,你要改成匹配這個正則,當然還有些服務器提示的是 Password,所以我們可以用正則 (p|P)ass(word|wd): 全部匹配,在 Action 中選擇 Send Text,在 Parameters 中填寫你的密碼,最后增加一個 \r 字符,\r 是回車,這就相當于你輸入了密碼,并按了下回車,最后,要把 Instant 的復選框選中,

我這里多加了一個正則運算式,因為第一次登錄服務器時會提示 Are you sure you want to continue connecting (yes/no)?,
現在在你的終端會話中雙指輕按觸控板,或者滑鼠右擊,就可以選擇你的 Profile 自動登錄了:

到了這一步還沒有結束,這個方法看似完美,其實是有問題的,假設你在這臺服務器上再通過 ssh 去登錄其他服務器,仍然會觸發 Triggers;再假設其他服務器的密碼和這臺服務器的密碼是不同的,這時候就會陷入尷尬的境地,不管你嘗試多少次,觸發器都會自動輸入之前設定的密碼,你將永遠登錄不上另一臺服務器,
還有一些其他的問題,比如你在終端中輸入的任何命令只要匹配了觸發器的正則,就會自動輸入密碼,使用體驗非常不好:

解決這個問題其實也很簡單,只需要提高正則匹配的準確度就行了,直接看圖:

現在再通過 ssh 登錄其他服務器,觸發器再也不會自動輸入密碼了:

在終端中輸入的命令也不會匹配到 password 和 Password 等這些單詞了:

到這一步算是完美解決了自動登錄的需求,但還是有一點小瑕疵,每臺服務器的觸發器正則運算式都是不一樣的,如果你要登錄的服務器很多,這個作業量將非常大,要不要用這種方法可以自己取舍,
下面我將介紹另外一種方案,相比之前的方案,下面的方案需要撰寫腳本,但它是可復用的,每臺服務器都可以使用同一個腳本,如果你要登錄的服務器數量很多,相比之下之前的方案作業量更大,
2. 通過 expect 自動登錄
expect 是一個自動化互動套件,主要應用于執行命令和程式時,系統以互動形式要求輸入指定字串,實作互動通信,它的自動互動流程如下:
spawn 啟動指定行程 ---> expect 獲取指定關鍵字 ---> send 向指定程式發送指定字符 ---> 執行完成退出
接下來我們將利用 expect 來實作 ssh 自動登錄,首先新建一個檔案 /usr/local/bin/iterm2Login.sh,內容如下:
#!/usr/bin/expect
set timeout 30
set host [lindex $argv 0]
# 這一行是設定一個變數的意思,變數名隨便起,盡量有意義,后面表示的是傳入的引數,0 表示第一個引數,后面會用到,
set port [lindex $argv 1]
set user [lindex $argv 2]
set pswd [lindex $argv 3]
spawn ssh -p $port $user@$host
# spawn 是 expect 環境的內部命令,它主要的功能是給 ssh 運行行程加個殼,用來傳遞互動指令,
expect {
"(yes/no)?"
{send "yes\n";exp_continue;}
-re "(p|P)ass(word|wd):"
{send "$pswd\n"}
}
# expect 也是 expect 環境的一個內部命令,用來判斷上一個指令輸入之后的得到輸出結果是否包含 "" 雙引號里的字串,-re 表示通過正則來匹配,
# 如果是第一次登錄,會出現 "yes/no" 的字串,就發送(send)指令 "yes\r",然后繼續(exp_continue),
interact
# interact:執行完成后保持互動狀態,把控制權交給控制臺,
argv 0, argv 1, argv 2, argv 3 三個引數依次為 ip、埠號、用戶名、密碼,
賦予腳本執行權限:
$ sudo chmod +x /usr/local/bin/iterm2Login.sh
將 Profile 中的 Command 部分替換成通過上面的腳本來登錄:

最后將觸發器中的所有規則都刪掉,只留下一個:

大功告成!
看來這個方法比上面的方法更加完美,因為 expect 只針對當前登錄的服務器,后續再通過當前服務器 ssh 登錄其他服務器,不會再自動輸入密碼什么的,如果服務器數量很多,也不用再一個一個去改觸發器規則,簡直太爽了,
當然,expect 也會遇到一些問題,比如無法正常使用 lrzsz,而這些問題在使用觸發器時是不存在的,當然,這些問題是可以解決的,解決之后,expect 將變成徹底完美的方案,觸發器的方案就可以拋之腦后了,
下面我將詳細介紹 expect 和 lrzsz 一起使用的問題,及其解決方案,
3. 使用 Zmodem 實作快速傳輸檔案
很多時候我們需要在本機和遠端服務器間進行檔案傳輸,通常都是使用 scp 命令進行傳輸,但其實通過 Zmodem 傳輸起來更方便,
什么是 Zmodem
Zmodem 是針對 modem 的一種支持錯誤校驗的檔案傳輸協議,Zmodem 是 Ymodem 的改進版,后者又是 Xmodem 的改進版,Zmodem 不僅能傳輸更大的資料,而且錯誤率更小,
利用 Zmodem 協議,可以在 modem 上發送 512 位元組的資料塊,Zmodem 包含一種名為檢查點重啟的特性,如果通信鏈接在資料傳輸程序中中斷,能從斷點處而不是從開始處恢復傳輸,
配置 iTerm2 支持 Zmodem
要讓 iTerm2 在遠端服務器上支持通過 Zmodem 協議傳輸,需要分別在服務端和客戶端進行相應配置,網上大多數檔案都只提到客戶端部分,因為收發方都必須有支持 Zmodem 協議的工具,才能進行正常收發,下面我們就來看看是如何進行配置的:
服務端配置
lrzsz 軟體包是 支持 Zmodem 協議的工具包, 其包含的 rz、sz 命令是通過 ZModem 協議在遠程服務器和終端機器間上傳下載檔案的利器,
為了正確通過 sz、rz 命令傳輸檔案,服務端需要安裝 lrzsz 軟體包的,
- Ubuntu 或 Debian
$ apt-get install lrzsz
- RHEL 或 CentOS
$ yum install lrzsz
客戶端配置
和服務器端一樣,客戶端同樣需要安裝 lrzsz 軟體包,這里通過 Homebrew 進行 lrzsz 軟體包安裝:
$ brew install lrzsz
配置 iTerm2
在全球最大同性交友網站 Github 上,已經有人共享了一個叫 “ZModem integration for iTerm 2” 的專案,我們只需下載其相應腳本,并進行簡單配置就可以很容易的在 iTerm2 上實作對 Zmodem 的支持,
專案地址:https://github.com/kuoruan/iterm2-zmodem
- 下載并安裝腳本
$ wget -qO /usr/local/bin/iterm2-zmodem.sh https://github.com/kuoruan/iterm2-zmodem/raw/master/iterm2-zmodem.sh
$ chmod +x /usr/local/bin/iterm2-zmodem.sh
- 配置 iTerm2 上的觸發器
打開 iTerm2 ,點擊 Preferences → Profiles 選擇指定的 Profile,然后繼續選擇 Advanced → Triggers,并點擊 Edit 添加兩個觸發器,

按如下內容添加兩個觸發器,首先增加 sz 指令的觸發器:
Regular expression: rz waiting to receive.\*\*B0100
Action: Run Silent Coprocess
Parameters: /usr/local/bin/iterm2-zmodem.sh send
Instant: checked
其次增加 rz 指令的觸發器:
Regular expression: \*\*B00000000000000
Action: Run Silent Coprocess
Parameters: /usr/local/bin/iterm2-zmodem.sh recv
Instant: checked
成功增加完成后的效果,類似下圖:

配置這兩個觸發器的作用就是讓 iTerm2 根據終端上顯示的字符通過指定的觸發器呼叫相應的發送和接收腳本,
使用 Zmodem 傳輸檔案
發送檔案到遠端服務器
- 在遠端服務器執行
rz命令 - 本地選擇檔案傳輸
- 等待傳輸指示消失
接收遠端服務器的檔案
- 在遠端服務器執行
sz filename1 filename2 … filenameN命令 - 本地選擇目錄保存
- 等待傳輸指示消失
Zmodem 與 expect 結合
如果你真的按照我提供的步驟操作了,最后你會發現根本無法傳輸檔案,其實這個問題不在于 Zmodem 本身,而是 expect 的問題,如果你將 Profile 的 Command 換成 ssh root@host 這種形式,就可以正常傳輸檔案了,
難道 expect 真的就沒有辦法了嗎?那之前的作業豈不是都化為烏有了?別慌,不但有辦法,而且這個辦法非常簡單,簡單的讓你想笑,只需要在 Profile 的 Command 命令前面加上一句 export LC_CTYPE=en_US 就行了:

收工!
4. 總結
本文詳細介紹了 macOS 平臺中的 iTerm2 如何使用觸發器和 expect 來實作 ssh 自動登錄遠程服務器,以及如何在 macOS 下通過 Zmodem快速傳輸檔案,當 expect 和 Zmodem 一起使用時,會出現一些莫名其妙的問題,本文最后也給出了解決方案,
參考
- 在 iTerm2 中使用 Zmodem 實作快速傳輸檔案
Kubernetes 1.18.2 1.17.5 1.16.9 1.15.12離線安裝包發布地址http://store.lameleg.com ,歡迎體驗, 使用了最新的sealos v3.3.6版本, 作了主機名決議配置優化,lvscare 掛載/lib/module解決開機啟動ipvs加載問題, 修復lvscare社區netlink與3.10內核不兼容問題,sealos生成百年證書等特性,更多特性 https://github.com/fanux/sealos ,歡迎掃描下方的二維碼加入釘釘群 ,釘釘群已經集成sealos的機器人實時可以看到sealos的動態,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/250507.html
標籤:其他
