天天看點

shell中自動互動的方法

第一種:輸入重定向Here Document

重定向操作符command << delimiter是一種非常有用的指令,shell将分界符delimiter之後直至下一個同樣的分界符之前的所有内容都作為輸入,遇到下一個分界符, shell就知道輸入結束了。最常見的delimiter分界符是EOF,當然完全可以自定為其他字元。

Here Document 是 Shell 中的一種特殊的重定向方式,用來将輸入重定向到一個互動式 Shell 腳本或程式。

它的基本的形式如下:

command << delimiter
    document
delimiter      

它的作用是将兩個 delimiter 之間的内容(document) 作為輸入傳遞給 command。

注意:
  • 結尾的delimiter 一定要頂格寫,前面不能有任何字元,後面也不能有任何字元,包括空格和 tab 縮進。
  • 開始的delimiter前後的空格會被忽略掉。

#!/bin/bash

ftp -i -n 192.168.167.187 << EOF

user hzc 123456

pwd

cd test

pwd

close

bye

EOF

    測試可以發現,如上代碼使用帳号名hzc,密碼123456成功登陸了ftp伺服器,并進入目錄,列印出了pwd。

第二種:管道,echo + sleep + |

    互動資訊的另一個自動輸入方法,管道,通過echo + sleep + | 。

#!/bin/bash

(echo "curpassword"

sleep 1

echo "newpassword"

sleep 1

echo "newpassword")|passwd

即:執行passwd指令後,輸入curpassword,1秒後輸入newpassword,1秒後再次輸入newpassword,達到把目前使用者的curpassword改成newpassword。

第三種:expect指令

    expect就是一個專門用來實作自動互動功能的工具,expect的文法可以參考相關資料,代碼如下:

#!/usr/bin/expect

spawn su root

expect "password: "

send "123456\r"

expect eof

exit

腳本命名為xx.exp

第四種:Here Document結合expect

expect <<!
這中間都是expect指令
!      

例如:

expect<<!

    spawn sudo chown -R adminHard:adminHard $newdir

    expect {

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

    }

!

注: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}

        }

        '