shell實現SSH自動登陸

2021-09-08 19:23:42 字數 3658 閱讀 7886

前些天在同事進行技術分享時,看到他竟然只輸入了一行命令./test.sh就成功登陸了開發機,甚是驚異,於是回來搜尋研究了一下,遂成此文。

在編寫ssh自動登陸指令碼之前,先說一下shell指令碼的基礎,此基礎不是一些語法什麼的,網上到處都是,這裡總結了一下shell指令碼的執行機制~

首先要說一下shell的幾種啟動方式,正是踩了指令碼啟動的坑,才使用原來十分鐘就搞定的指令碼,花了兩個小時才搞定。同時也使得我們執行shell,知其所以然。

通過檔名執行

shell指令碼可以直接通過檔名執行,需要注意的是檔案需要執行許可權。通過sudo chmod +x ./file_name.sh來給檔案新增執行許可權;

指定指令碼直譯器來執行檔案

我們常用的sh file_name.sh就是指定了指令碼直譯器/bin/sh來解釋執行指令碼;常見的指令碼直譯器還有:/bin/bash等,我們可以使用ls -l /bin/*sh命令來檢視當前可用的指令碼直譯器;

使用. ./file_name或source命令執行指令碼

這種方式不會像前兩種方式一樣fork乙個子程序去執行指令碼,而是使用當前shell環境執行,用於 .bashrc或者.bash_profile被修改的時候,我們不必重啟shell或者重新登入系統,就能使當前的更改生效。

我們寫乙個shell指令碼時,總是習慣在最前面加上一行#!/binbash,它就是指令碼的shebang,至於為什麼叫這麼個奇怪的名字,c語言和unix的開發者丹尼斯·里奇稱它為可能是類似於"hash-bang"的英國風描述性文字

貼一段wiki上的解釋:

在電腦科學中,shebang是乙個由井號和嘆號構成的字串行,其出現在文字檔案的第一行的前兩個字元。 在檔案中存在shebang的情況下,類unix作業系統的程式載入器會分析shebang後的內容,將這些內容作為直譯器指令,並呼叫該指令,並將載有shebang的檔案路徑作為該直譯器的引數。

簡單的說,它指示了此指令碼執行時的直譯器,所以,使用檔名直接執行shell指令碼時,必須帶上shebang; 此外,我們還可以在shebang後面直接附加選項,執行時我們預設使用選項執行;

test.shshebang#!/bin/sh -x,那我們執行指令碼時:

./test.sh hello

相當於:

bin/sh -x ./test.sh hello;

而編寫乙個ssh自動登陸指令碼,需要用到的shebang(直譯器)為/usr/bin/expect;

需要注意的是:在指定指令碼直譯器來執行指令碼時,shebang會被指定的指令碼直譯器覆蓋,即優先使用指定的指令碼直譯器來執行指令碼(習慣性地用sh ./test.sh卻提示command not found)

expect是乙個能實現自動和互動式任務的直譯器,它也能解釋常見的shell語法命令,其特色在以下幾個命令:

spawn command命令會fork乙個子程序去執行command命令,然後在此子程序中執行後面的命令;

在ssh自動登陸指令碼中,我們使用spawn ssh user_name@ip_str,fork乙個子程序執行ssh登陸命令;

expect命令是expect直譯器的關鍵命令,它的一般用法為expect "string",即期望獲取到string字串,可在在string字串裡使用 * 等萬用字元;

string與命令列返回的資訊匹配後,expect會立刻向下執行指令碼;

set timeout n命令將expect命令的等待超時時間設定為n秒,在n秒內還沒有獲取到其期待的命令,expect 為false,指令碼會繼續向下執行;

send命令的一般用法為send "string",它們會我們平常輸入命令一樣向命令列輸入一條資訊,當然不要忘了在string後面新增上\r表示輸入回車;

interact命令很簡單,執行到此命令時,指令碼fork的子程序會將操作權交給使用者,允許使用者與當前shell進行互動;

以下是乙個完成版的指令碼test.sh

#!/usr/bin/expect                   // 指定shebang  set timeout 3                       // 設定超時時間為3秒 spawn ssh user_name@172.***.***.*** // fork乙個子程序執行ssh命令 expect "*password*"                 // 期待匹配到 'user_name@ip_string's password:'  send "my_password\r"                // 向命令列輸入密碼並回車 send "sudo -s\r"  send "cd /data/logs\r"              // 幫我切換到常用的工作目錄 interact                            // 允許使用者與命令列互動

執行sudo chmod +x ./test.sh命令給shell指令碼新增執行許可權;

執行./test.sh命令,一鍵登陸成功!

簡單的幾個命令,,搭配起來解決了與命令列的互動問題後,很多複雜的功能也不在話下了~

指令碼完成了,可是還是有些小瑕疵:

這裡我們想到了linux的alias命令:

alias命令使用方式為alias alias_name="ori_command",將alias_name設定為ori_command的別名,這樣我們輸入執行alias_name,就相當於執行了ori_command;

可是,我們會發現,當你關閉當前shell後,再開啟乙個shell視窗,再使用alias_name,系統提示command not found;

有沒有能保持命令的方式呢?編輯bash_profile檔案。

我們編輯bash_profile檔案,此檔案會在終端視窗建立的時候首先執行一次,所以可以幫我們再設定一次別名;

執行命令vim ~./bash_profile,在檔案內部新增:

alias alias_name="/root_dir/../file_name.sh

儲存後,再使用. ~./bash_profilesource ~./bash_profile在當前指令碼執行一遍設定別名命令,完成設定;

這樣,我們無論在哪個目錄,只要輸入alias_name命令,回車,真正的一鍵登陸!

作為乙個程式猿,時刻保持著偷懶意識(當然此偷懶非彼偷懶。。。),在類unix系統中,不要浪費了shell這種神奇的工具,讓計算機為我們服務~

乙個多月沒寫部落格了,最近在看apue,unp一套的書,c和unix上入門尚淺,不敢亂寫誤人子弟;平常自己用記事本做的筆記也比較散亂,不成系統;

**:

shell實現SSH自動登陸

公司開發使用docker,每次登陸自己開發機總要輸入ssh user name ip string,然後再確認輸入password,手快了還經常會輸錯。作為乙個懶人,肯定要找乙個取巧的方式,檢視了下ssh命令,由於它要進行一次跟伺服器的加密互動,所以沒有直接附帶密碼登陸的選項,只好作罷。前些天在同事...

shell實現SSH自動登陸

公司開發使用docker,每次登陸自己開發機總要輸入ssh user name ip string,然後再確認輸入password,手快了還經常會輸錯。作為乙個懶人,肯定要找乙個取巧的方式,檢視了下ssh命令,由於它要進行一次跟伺服器的加密互動,所以沒有直接附帶密碼登陸的選項,只好作罷。前些天在同事...

shell實現SSH自動登陸

前些天在同事進行技術分享時,看到他竟然只輸入了一行命令.test.sh就成功登陸了開發機,甚是驚異,於是回來搜尋研究了一下,遂成此文。在編寫ssh自動登陸指令碼之前,先說一下shell指令碼的基礎,此基礎不是一些語法什麼的,網上到處都是,這裡總結了一下shell指令碼的執行機制 首先要說一下shel...