iTerm2 實現 ssh 自動登陸,並使用 Zmodem 實現快速傳輸文件

原文連接:fuckcloudnative.io/posts/iterm…html

對於 YAML 工程師來講,咱們常常須要 ssh 登陸不一樣的服務器,每次登陸時都要經歷兩個步驟:linux

  1. 輸入 ssh root@host-ip
  2. 輸入密碼

每次都重複這樣的操做,不只麻煩,還要記憶好多東西。對於 Windows 用戶來講,可使用 Xshell 來實現自動登陸功能,macOS 用戶就比較麻煩了。iTerm2macOS 平臺上最強大的終端工具,雖然默認沒有提供自動登陸的功能,但咱們能夠嘗試經過它提供的其餘功能來打造自動登陸的功能。git

固然,既然我寫了這篇文章,就說明我已經找到了方法,下面就直接開門見山放乾貨。我想提醒你的是,我這裏提供的方法絕對是你歷來沒有見過的,你可能會以爲網上能搜到不少和我相似的方案,但若是你仔細看就能看出區別來,網上的方案都是不完美的,和其餘功能同時使用時會出現莫名其妙的問題(具體是什麼問題後面我會講到),我把這些問題都解決了,獲得了一個極其完美的方案。github

本文將提供兩種自動登陸方案,首先來看第一種方案。web

1. 經過觸發器自動登陸

iTerm2 有一個很是強大的功能叫觸發器(Trigger),觸發器是用戶可配置的正則表達式,當終端會話接收到與正則表達式相匹配的文本時,會執行相關的操做。這裏的操做包括突出顯示匹配的文本,顯示警報,發回文本等等。正則表達式

觸發器的一種高級用法是捕獲與正則表達式匹配的輸出,並在工具欄中顯示這些匹配線。 例如,您能夠建立一個匹配編譯器錯誤的觸發器。 當你運行時,錯誤會出如今你的窗口一側,你能夠點擊每個跳到它的右邊。 更多信息可在 Captured Output 手冊中找到。shell

本文將利用觸發器來實現 ssh 自動登陸的功能。首先點擊 Preference -> Profiles,選中你要登陸的服務器,Command 這裏填寫你的 ssh 登陸的 ip 和用戶名,若是端口不是 22 還要指定端口:express

而後點擊 Advanced,找到 Trriggers,點擊 editbash

在 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 將變成完全完美的方案,觸發器的方案就能夠拋之腦後了。

下面我將詳細介紹 expectlrzsz 一塊兒使用的問題,及其解決方案。

3. 使用 Zmodem 實現快速傳輸文件

不少時候咱們須要在本機和遠端服務器間進行文件傳輸,一般都是使用 scp 命令進行傳輸,但其實經過 Zmodem 傳輸起來更方便。

什麼是 Zmodem

Zmodem 是針對 modem 的一種支持錯誤校驗的文件傳輸協議。ZmodemYmodem 的改進版,後者又是 Xmodem 的改進版。Zmodem 不只能傳輸更大的數據,並且錯誤率更小。

利用 Zmodem 協議,能夠在 modem 上發送 512 字節的數據塊。Zmodem 包含一種名爲檢查點重啓的特性,若是通訊連接在數據傳輸過程當中中斷,能從斷點處而不是從開始處恢復傳輸。

配置 iTerm2 支持 Zmodem

要讓 iTerm2 在遠端服務器上支持經過 Zmodem 協議傳輸,須要分別在服務端和客戶端進行相應配置。網上大多數文檔都只提到客戶端部分。由於收發方都必須有支持 Zmodem 協議的工具,才能進行正常收發。下面咱們就來看看是如何進行配置的:

服務端配置

lrzsz 軟件包是 支持 Zmodem 協議的工具包。 其包含的 rzsz 命令是經過 ZModem 協議在遠程服務器和終端機器間上傳下載文件的利器。

爲了正確經過 szrz 命令傳輸文件,服務端須要安裝 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 的支持。

項目地址:github.com/kuoruan/ite…

  • 下載並安裝腳本
$ 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 ,點擊 PreferencesProfiles 選擇指定的 Profile。而後繼續選擇 AdvancedTriggers,並點擊 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 的問題,若是你將 ProfileCommand 換成 ssh root@host 這種形式,就能夠正常傳輸文件了。

難道 expect 真的就沒有辦法了嗎?那以前的工做豈不是都化爲烏有了?別慌,不但有辦法,並且這個辦法很是簡單,簡單的讓你想笑。只須要在 Profile 的 Command 命令前面加上一句 export LC_CTYPE=en_US 就好了:

收工!

4. 總結

本文詳細介紹了 macOS 平臺中的 iTerm2 如何使用觸發器和 expect 來實現 ssh 自動登陸遠程服務器,以及如何在 macOS 下經過 Zmodem快速傳輸文件。當 expect 和 Zmodem 一塊兒使用時,會出現一些莫名其妙的問題,本文最後也給出瞭解決方案。

參考

相關文章
相關標籤/搜索