天天看點

shell實作SSH自動登陸 shell腳本基礎 expect解釋器完成腳本alias别名總結

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

在編寫ssh自動登陸腳本之前,先說一下shell腳本的基礎,此基礎不是一些文法什麼的,網上到處都是,這裡總結了一下shell腳本的運作機制~

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

shell腳本可以直接通過檔案名執行,需要注意的是檔案需要執行權限。通過 <code>sudo chmod +x ./file_name.sh</code> 來給檔案添加執行權限;

我們常用的 <code>sh file_name.sh</code> 就是指定了腳本解釋器 <code>/bin/sh</code>來解釋執行腳本;常見的腳本解釋器還有:<code>/bin/bash</code>等,我們可以使用<code>ls -l /bin/*sh</code>指令來檢視目前可用的腳本解釋器;

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

我們寫一個shell腳本時,總是習慣在最前面加上一行 <code>#!/binbash</code>,它就是腳本的<code>shebang</code>,至于為什麼叫這麼個奇怪的名字,C語言和Unix的開發者丹尼斯·裡奇稱它為<code>可能是類似于"hash-bang"的英國風描述性文字</code>;

貼一段wiki上的解釋:

在計算機科學中,Shebang是一個由井号和歎号構成的字元串行,其出現在文本檔案的第一行的前兩個字元。 在檔案中存在Shebang的情況下,類Unix作業系統的程式載入器會分析Shebang後的内容,将這些内容作為解釋器指令,并調用該指令,并将載有Shebang的檔案路徑作為該解釋器的參數。

簡單的說,它訓示了此腳本運作時的解釋器,是以,使用檔案名直接執行shell腳本時,必須帶上shebang; 此外,我們還可以在shebang後面直接附加選項,執行時我們預設使用選項執行;

如 <code>test.sh</code>的<code>shebang</code>為 <code>#!/bin/sh -x</code>,那我們執行腳本時:

<code>./test.sh hello</code>

相當于:

<code>bin/sh -x ./test.sh hello</code>;

而編寫一個ssh自動登陸腳本,需要用到的shebang(解釋器)為 <code>/usr/bin/expect</code>;

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

expect是一個能實作自動和互動式任務的解釋器,它也能解釋常見的shell文法指令,其特色在以下幾個指令:

<code>spawn command</code>指令會fork一個子程序去執行command指令,然後在此子程序中執行後面的指令;

在ssh自動登陸腳本中,我們使用 <code>spawn ssh user_name@ip_str</code>,fork一個子程序執行ssh登陸指令;

expect指令是expect解釋器的關鍵指令,它的一般用法為 <code>expect "string"</code>,即期望擷取到string字元串,可在在string字元串裡使用 * 等通配符;

string與指令行傳回的資訊比對後,expect會立刻向下執行腳本;

<code>set timeout n</code>指令将expect指令的等待逾時時間設定為n秒,在n秒内還沒有擷取到其期待的指令,expect 為false,腳本會繼續向下執行;

send指令的一般用法為 <code>send "string"</code>,它們會我們平常輸入指令一樣向指令行輸入一條資訊,當然不要忘了在<code>string</code>後面添加上 <code>\r</code> 表示輸入回車;

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

以下是一個完成版的腳本 <code>test.sh</code>:

執行 <code>sudo chmod +x ./test.sh</code>指令給shell腳本添加執行權限;

運作 <code>./test.sh</code>指令,一鍵登陸成功!

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

腳本完成了,可是還是有些小瑕疵:

輸入<code>./file_name.sh</code>指令太長。。。

隻能在腳本目錄中才能執行,不然使用絕對路徑輸出的指令更長。

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

alias指令使用方式為 <code>alias alias_name="ori_command"</code>,将alias_name設定為ori_command的别名,這樣我們輸入執行alias_name,就相當于執行了ori_command;

可是,我們會發現,當你關閉目前shell後,再打開一個shell視窗,再使用alias_name,系統提示<code>command not found</code>;

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

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

執行指令<code>vim ~./bash_profile</code>,在檔案内部添加:

<code>alias alias_name="/root_dir/../file_name.sh</code>

儲存後,再使用 <code>. ~./bash_profile</code>或<code>source ~./bash_profile</code> 在目前腳本執行一遍設定别名指令,完成設定;

這樣,我們無論在哪個目錄,隻要輸入<code>alias_name</code>指令,回車,真正的一鍵登陸!

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

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

 轉自:http://www.cnblogs.com/zhenbianshu/p/5867440.html 

心得:看到此文,親身實踐,頓覺收獲頗豐,遂轉載作為筆記!程式員就是要越簡潔越好,提升效率! 

若轉載請注明出處!若有疑問,請回複交流!