天天看點

【shell】shell實作互動

一、shell

自動輸入yes

echo "y" | yum install wget ,等同于yum -y  install wget

自動輸入回車

echo -e "\n" | yum remove wget

**`echo -e` 的小知識**

若字元串中出現以下字元,則特别加以處理,而不會将它當成一般文字輸出:

​<code>​\a​</code>​ 發出警告聲;

​<code>​\b​</code>​ 删除前一個字元;

​<code>​\c​</code>​ 最後不加上換行符号;

​<code>​\f​</code>​ 換行但光标仍舊停留在原來的位置;

​<code>​\v​</code>​ 與\f 相同;

​<code>​\n​</code>​ 換行且光标移至行首;

​<code>​\r​</code>​ 光标移至行首,但不換行;

​<code>​\t​</code>​ 插入 ​<code>​tab​</code>​ 符号;

​<code>​\\​</code>​ 插入 ‘' 字元;

​<code>​\nnn​</code>​ 插入 nnn(八進制)所代表的 ascii 字元;

輸入多行指令我們需要借助輸入重定向操作符 ​<code>​&lt;&lt;​</code>​

以下面這個腳本為例

multi.sh

借助 ​<code>​&lt;&lt;​</code>​ 符号進行自動化輸入

但是有時候這種方法并不生效,比如 ​<code>​ssh-keygen​</code>​ 指令,那隻有借助強大的 ​<code>​expect​</code>​ 指令了

我們還可以使用 read指令的-n 選項,此選項後面需要接一個數字,可以限制輸入内容的個數。

目前,我們輸入的内容都是可見的,但有些敏感的資料,如密碼,信用卡号等資訊,輸入時并不想可見。那麼可以使用​<code>​read -s​</code>​。

【shell】shell實作互動

這時再輸入時,就有一個鑰匙的辨別,而且輸入時不可見。

 二、expect

 expect是一個免費的程式設計工具,用來實作自動和互動式任務通信,安裝 ​<code>​yum install -y expect​</code>​ 

expect的文法:

關鍵指令send、expect、spawn和interact:

send:用于向程序發送字元串,注意一定要在末尾加\r回車

expect:從程序接收字元串

spawn:啟動新的程序

interact:允許使用者繼續互動

expect 有兩種用法,一種是直接寫 expect 解釋器的腳本,和 bash 類似,以 ​<code>​#!/usr/bin/expect​</code>​ 開頭

下面是一個合格的 expect 腳本示例

需要注意的是,在 expect 解釋器内, 除了幾個特定關鍵字的指令,其他指令都不可用,這種方式适用于執行指令較少,單次需要互動較多的自動化腳本

第二種用法是在 bash 腳本中執行 expect 配合重定向操作符, 在有大量腳本需要執行的情況下推薦使用該方式

下面是我在 ​<code>​certbot​</code>​ 指令時使用的 shell 腳本,以供參考

 expect是關鍵的部分,在英文中,expect有“期待”的意思,采用了tcl的模式-動作文法,此文法有以下幾種模式:

單一分支文法:

多分支模式文法:

例:expect腳本ssh.exp内容:

經常要面臨在某個環境編輯代碼然後需要自動同步更新到其他機器的情況。對于這種問題,我們也可以借助expect腳本來實作。

例:

配置檔案為sync.cfg:

shell腳本sync_ftp.sh内容:

expect腳本sync_ftp.exp:

由于檔案同步是每天都需要進行的,是以可以結合定時任務crond來進一步簡化工作。crond是類unix系統下用來周期執行某種任務或者事件的一個守護程序,配置資訊存放在/etct/crontab檔案中。crontab是系統服務crond的控制指令。關于crontab的使用,在程序章節已經進行了介紹,這裡就不再贅述了。

expect指令是很強大的,可以實作各種自動化操作。自此,你不僅可以寫出各種厲害的shell腳本,還能讓它們自動執行,對于日常工作的處理将會有大大的提升。

注:expect指令

[set timeout 30]     

    基本上認識英文的都知道這是設定逾時時間的,現在你隻要記住他的計時機關是:秒   

[spawn ssh -l username 192.168.1.1]    

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

spawn是進入expect環境後才可以執行的expect内部指令,如果沒有裝expect或者直接在預設的shell下執行是找不到spawn指令的。是以不要用 “which spawn“之類的指令去找spawn指令。好比windows裡的dir就是一個内部指令,這個指令由shell自帶,你無法找到一個dir.com 或 dir.exe 的可執行檔案。    

    它主要的功能是給ssh運作程序加個殼,用來傳遞互動指令。   

[expect "password:"]   

    這裡的expect也是expect的一個内部指令,有點暈吧,expect的shell指令和内部指令是一樣的,但不是一個功能,習慣就好了。這個指令的意思是判斷上次輸出結果裡是否包含“password:”的字元串,如果有則立即傳回,否則就等待一段時間後傳回,這裡等待時長就是前面設定的30秒   

[send "ispass\r"]   

    這裡就是執行互動動作,與手工輸入密碼的動作等效。   

    溫馨提示: 指令字元串結尾别忘記加上 “\r”,如果出現異常等待的狀态可以核查一下。   

[interact]    

    執行完成後保持互動狀态,把控制權交給控制台,這個時候就可以手工操作了。如果沒有這一句登入完成後會退出,而不是留在遠端終端上。如果你隻是登入過去執行一段指令就退出,可改為[expect eof]

expect可以讓你使用“-c”選項,直接在指令行中執行它,例如:

expect -c '

        spawn git pull

        expect {

        "usernam*" {send "[email protected]\n"; exp_continue }

        "passwor*" {send "$git_code_password\n" ; exp_continue}

        }

        '