expect實現非交互

1、exepct介紹

expect命令是一個實現交互功能的軟件套件,是基於TCL的腳本編程語言,在企業運維中,系統會以交互的形式要求運維人員輸入指定的字符串,以後才能繼續執行命令。例如:爲用戶設置密碼時,通常狀況下須要手工輸入兩次密碼,好比使用ssh鏈接遠程服務器時,第一次連和系統實現兩次交互。mysql

簡單的說,expect用來自動實現與交互程序通訊的,無需管理員手工干預linux

spawn啓動指定進程>expect獲取期待的關鍵字>send向指定進程發送字符>進程執行完畢,退出sql

 

2、expect程序自動交互

expect程序中的命令是expect的核心shell

spawn  [選項]  [須要交互的命令或程序]編程

例如:vim

       spawn ssh root@192.168.4.5 uptime數組

在spawn命令的後面,直接要加上要執行的命令或程序bash

 

expect命令語法服務器

在expect自動交互的執行過程當中,當使用spawn命令執行一個命令或程序以後,會提示某些交互信息,expect命令的做用就是獲取spawn命令執行的信息,看看是否有事先指定的相匹配,一旦匹配上指定的內容就執行expect後面的動做。運維

expect    表達式    [動做]

例如:

spawn ssh root@192.168.4.5 uptime

expect 「*password」 {send 「666666\r」}

send 發送字符串

 

固然,他也能夠在一個expect匹配中屢次匹配不一樣的字符串,並給出不一樣的處理動做,此時,只須要將匹配的全部字符串放在一個{}大括號中就能夠了,好須要藉助exp_continue指令實現繼續匹配。

 

2.1 實現自動交互

#!/usr/bin/expect

spawn ssh root@192.168.4.5 uptime

expect {

        "yes/no" {exp_send "yes\r";exp_continue}

        "*password" {exp_send "666666\r"}

}

expect eof

 

expect_send和send相似,\r 回車

expect{},相似多行expect。

exp_continue 匹配多個字符串,須要在每次匹配並執行動做後繼續匹配,加上exp_continue

exp_eof 想要輸出結果,必須加eof,表示expect結束

 

2.2利用expect響應shell腳本中的多個read讀入

[root@localhost ~]# vim xinxi.sh

#!/bin/bash

read -p "pls input your username:" name

read -p "pls input your password:" pass

read -p "pls input your email:" mail

echo -n "your name is $name ,"

echo -n "your passwordis $pass ,"

echo "your emali is $mail"

 

[root@localhost ~]# sh xinxi.sh

pls input your username:calabash

pls input your password:666666

pls input your email:calabash@163.com

your name is calabash ,your passwordis 666666 ,your emali is calabash@163.com

用expect自動化腳本,實現自動輸入多個字符串

[root@localhost ~]# vim expxinxi.exp

#!/usr/bin/expect

spawn /bin/sh xinxi.sh

expect {

 

        "username" {exp_send "calabash\r";exp_continue}

        "password" {send "666666\r";exp_continue}

        "email" {exp_send "calabash@163.com\r"}

}

expect eof

執行,所有自動輸入,實現了自動化

[root@localhost ~]# expect expxinxi.exp

spawn /bin/sh xinxi.sh

pls input your username:calabash

pls input your password:666666

pls input your email:calabash@163.com

your name is calabash ,your passwordis 666666 ,your emali is calabash@163.com

 

send_user 能夠用來打印expect腳本的信息,相似shell裏的echo命令

[root@localhost ~]# vim me.exp

#!/usr/bin/expect

send_user "I am calabash. \n"

send_user "I am a linuxer. \t"

send_user "mysql email is calabash@163.com\n"

 

[root@localhost ~]# expect me.exp

I am calabash.

I am a linuxer.       mysql email is calabash@163.com

 

\n   換行

\t   tab鍵

 

exit命令相似於shell腳本的exit,即直接退出expect腳本,除了最基本的退出,還能夠利用exit作一些提示

例如:

[root@localhost ~]# vim me.exp

#!/usr/bin/expect

send_user "I am calabash. \n"

send_user "I am a linuxer. \t"

send_user "mysql email is calabash@163.com\n"

exit -onexit {

        send_user "Good bye.\n"

}

[root@localhost ~]# expect me.exp

I am calabash.

I am a linuxer.       mysql email is calabash@163.com

Good bye.

 

2.3 經常使用命令總結

spawn:用過spawn執行一個程序或命令,以後全部的expect操做都在這個執行的程序或命令中執行。

expect:獲取spawn程序的交互信息,查看是否和其事先指定的信息想匹配。

send:當expect匹配了指定的字符串後,發送指定的字符串給系統,這些命令能夠支持一些特殊的轉義符號,例如: \r回車 \n換行       \t  tab等

exp_contine:繼續匹配expect程序或命令

send_user:打印腳本信息

exit:退出expect腳本,也能夠作清理或提示工做

 

3、expect程序變量

3.1普通變量

定義變量:

set  變量名        變量值

 

打印變量:

puts     $變量名

示例:

[root@localhost ~]# vim shili.exp

#!/usr/bin/expect

set password "666666"

puts $password

send_user "$password\n"

 

[root@localhost ~]# expect shili.exp

666666

666666

 

3.2 特殊參數變量

在expect裏也有與shell腳本里的$0 $1 $2 等相似的特殊參數變量,用於接收控制expect腳本傳參

在expect中$argv表示參數數組,可使用[lindex $argv n]接收expet腳本傳參,n從0開始,分別表示第一個[lindex $argv 0]參數、第二個[lindex $argv 1]、第三個[lindex $argv 2參數]

例如:

[root@localhost ~]# vim shili.exp

#!/usr/bin/expect

set file [lindex $argv 0]

set host [lindex $argv 1]

set dir [lindex $argv 2]

puts "$file\t $host\t $dir\n"

puts $argc

puts $argv0

 

加三個位置參數

[root@localhost ~]# expect shili.exp a.txt 192.168.4.5 /root

a.txt     192.168.4.5   /root

 

3

shili.exp

$argc  表示傳參的個數

$argv0  表示腳本自己的名字

 

3.3 關鍵字變量

timeout是一個控制時間的關鍵字變量,是一個全局性時間的控制開關,能夠經過爲這個變量賦值來規定整個expect操做的時間。由於做用於全局,即便命令沒有錯誤,到了時間仍然會激活這個變量,此外,到時間後還會激活一個處理及提示信息開關。

示例:

此腳本測試超時返回值,因此不設置密碼,5秒後超時返回

 

[root@localhost ~]# vim shili.exp

#!/usr/bin/expect

spawn ssh roo@192.168.4.5 uptime

set timeout 5

expect "yes/no" {exp_send "yes\r;exp_continue"}

expect timeout {puts "Request timeout by calabash.";return}

 

[root@localhost ~]# expect shili.exp

spawn ssh roo@192.168.4.5 uptime

roo@192.168.4.5's password: Request timeout by calabash.

 

 

此外,在expect{}用法,還能夠這樣使用timeout

[root@localhost ~]# vim shili.exp

#!/usr/bin/expect

spawn ssh roo@192.168.4.5 uptime

expect {

        -timeout 3

        "yes/no" {exp_send "yes\r";exp_continue}

        timeout {puts "Request timeout by calabash.";return}

}

 

[root@localhost ~]# expect shili.exp

spawn ssh roo@192.168.4.5 uptime

roo@192.168.4.5's password: Request timeout by calabash.

4、expect程序中的if條件語句

4.1 if語句的語法

       if  { 條件表達式 }  {

       指令

}

或者

if  { 條件表達式 }  {

       指令

}  else  {

       指令

}

 

注意:if關鍵字後面要有空格,else關鍵字先後要有空格

{條件表達式}  大括號裏能夠沒有空格, 外面先後要有空格

 

4.2 if判斷示例

 使用if語句判斷腳本傳參的個數,無論是否符合都給予提示

[root@localhost ~]# vim shili.exp

#!/usr/bin/expect

if { $argc != 26 } {

        puts "bad."

} else {

        puts "good."

}

 

[root@localhost ~]# expect shili.exp

bad.

[root@localhost ~]# expect shili.exp {a..z}

good.

 

5、expect生產環境案例

5.1 實現自動交互的腳本

[root@G ~]# vim zd.exp

#!/usr/bin/expect

if { $argc != 2 } {

        puts "usage: expect $argv0 ip command"

exit

}

#

set ip [lindex $argv 0]

set cmd [lindex $argv 1]

set password "666666"

#

spawn ssh root@$ip $cmd

expect {

        "yes/no" {send "yes\r";exp_continue} &> /dev/null

        "*password" {send "$password\r"} &> /dev/null

}

expect eof

腳本後加上ip和命令

[root@G ~]# expect zd.exp 192.168.4.5 uptime

spawn ssh root@192.168.4.5 uptime

root@192.168.4.5's password:

 05:15:09 up 15 min,  2 users,  load average: 0.00, 0.00, 0.00

 

5.2 利用for循環查看多臺

現有2臺服務器,須要用管理機去查看

Ip地址

主機名

角色

192.168.4.4

G

管理機

192.168.4.5

b1

被管理機

192.168.4.6

b2

被管理機

 

[root@G ~]# vim pl.sh

#!/bin/bash

if [ $# -ne 1 ];then

        echo $"USAGE:$0 cmd"

        exit 1

fi

cmd=$1

for n in 5 6

do

        expect zd.exp 192.168.4.$n "$cmd"

done

 

[root@G ~]# sh pl.sh uptime

spawn ssh root@192.168.4.5 uptime

root@192.168.4.5's password:

 01:00:21 up 36 min,  2 users,  load average: 0.00, 0.00, 0.00

spawn ssh root@192.168.4.6 uptime

root@192.168.4.6's password:

 01:00:21 up 35 min,  2 users,  load average: 0.00, 0.00, 0.00

 

5.3 免交互發送文件

[root@G ~]# vim scpfile.exp

#!/usr/bin/expect

if { $argc != 3 } {

        puts "usage: expect $argv0 file host dir"

        exit

}

#

set file [lindex $argv 0]

set host [lindex $argv 1]

set dir [lindex $argv 2]

set password "666666"

spawn scp -rp -P22 $file root@$host:$dir

expect {

        "yes/no" {send "yes/r";exp_continue}

        "*password" {send "$password\r"}

}

expect eof

 

發送文件

[root@G ~]# expect scpfile.exp abc 192.168.4.6 /root/

spawn scp -rp -P22 abc root@192.168.4.6:/root/

root@192.168.4.6's password:

查看發送結果

[root@G ~]# expect zd.exp 192.168.4.6 ls

spawn ssh root@192.168.4.6 ls

root@192.168.4.6's password:

abc

anaconda-ks.cfg

install.log

install.log.syslog

 

5.4 利用shell循環批量發送文件

[root@G ~]# vim scpfile.sh

#!/bin/bash

if [ $# -ne 2 ];then

        echo $"USAGE:$0 file dir"

        exit 1

fi

#

file=$1

dir=$2

for n in 5 6

do

        expect scpfile.exp $file 192.168.4.$n $dir

done

 

[root@G ~]# sh scpfile.sh wangluyu /root/

spawn scp -rp -P22 wangluyu root@192.168.4.5:/root/

root@192.168.4.5's password:

spawn scp -rp -P22 wangluyu root@192.168.4.6:/root/

root@192.168.4.6's password:

相關文章
相關標籤/搜索