大数据兼云计算(王明龙)讲师-LINUX-DAY13-EXPECT

**

EXPECT全解

**

  Expect是Unix系统中用来进行自动化控制和测试的软件工具,由DonLibes制作,作为Tcl脚本语言的一个扩展,应用在交互式软件中如telnet,ftp,Passwd,fsck,rlogin,tip,ssh等等。该工具利用Unix伪终端包装其子进程,允许任意程序通过终端接入进行自动化控制;也可利用Tk工具,将交互程序包装在X11的图形用户界面中。
  简单地说,expect是一个工具,可以根据用户设定的规则和系统进程进行自动化交互,例如远程登陆的密码输入、自动化的执行远程命令。

  1. 介绍
    expect是建立在tcl(参见:Tcl/Tk快速入门 )基础上的一个工具,它可以让一些需要交互的任务自动化地完成。相当于模拟了用户和命令行的交互操作。
    一个具体的场景:远程登陆服务器,并执行命令
    登录时输入密码需要交互,bash脚本无法完成,可以使用expect来完成。

  2. 安装
    下面介绍两种安装方式

yum 安装
yum install -y expect

源码编译安装
expect 依赖于 tcl, 所以需要首先安装 tcl。可以使用rpm检查是否已经安装tcl:

rpm -qa | grep tcl

如果已安装,则会打印出tcl软件信息

安装过程参考:linux expect 安装 http://www.cnblogs.com/daojian/archive/2012/10/10/2718390.html
tcl 地址:https://sourceforge.net/projects/tcl/files/Tcl/ 选择一个版本
expect 地址:https://sourceforge.net/projects/expect/files/Expect/ 选择一个版本
注意:wget 下载的时候需要加上 –no-check-certificate, 不检查网站证书

  1. 原理与工作机制
    首先使用 spawn 开启一个会话,然后使用 expect-send 对来执行交互式操作。
    spawn 后面跟上一个命令操作,表示开启一个会话。expect 等待输出特定的字符串(通常是提示符),然后使用send 发送交互字符串。比如:

spawn ssh username@host # 远程登录

expect “*assword” # 提示为:”username@host’s password:”, 等待用户输入密码
send “${password}\r” # 这时使用send模拟用户输入密码的字符串,完成登录验证

  1. 基本语法介绍
    脚本解释器
    脚本中首先引入文件,表明使用的是哪一个shell

!/usr/bin/expect

set
设置会话超时时间为30s, 若不限制超时时间则应设置为-1
set timeout 30

set 还可以设置变量

使用变量语句: p a r a m {param}({}用来避免param和后面的字符串拼接起来导致错误)

set param “param_str”
set param 1

spawn
spawn 后面跟一个命令,开启一个会话

spawn ${cmd} # for example : spawn su root
expect - send
expect 接收命令执行后的输出,然后和期望字符串匹配,若对应这执行相应的send来发送交互信息。

expect “ case1" {send " respond1\r”} # 这一行等同于下面两行

expect “ c a s e 1 s e n d response1\r”

expect 可以有多个分支,就像switch语句一样。

expect
{
c a s e 1 " s e n d " $ r e s p o n s e 1 \r case2" {send " response2\r”}      “ case3" {send "$response3\r”}
}

结束符
expect eof :等待执行结束,若没有这一句,可能导致命令还没执行,脚本就结束了
interact : 执行完成后保持交互状态, 这时可以手动输入信息
注:expect eof 与 interact 二选一即可

接收参数
参数存在argv中,使用第一个参数如下:

set param0 [lindex a r g v 0 ] 1 2 argc表示参数个数,判断语句如下:

if { argc < 1} {      #do something      send_user “usage: argv0 … ”
exit
注: a r g v 0 [ l i n d e x argv 0]是第一个参数 param1, [lindex $argv 1]是第二个参数 param2, 以此类推
send_user 用来显示信息到父进程(一般为用户的shell)的标准输出。

**

expect_scp

**

一.解决scp交互

vim expect_scp 解决交互执行的文件


!/usr/bin/expect

set timeout 10
set host [lindex a r g v 0 ] s e t u s e r n a m e [ l i n d e x argv 1]
set password [lindex a r g v 2 ] s e t s r c f i l e [ l i n d e x argv 3]
set dest_file [lindex a r g v 4 ] s p a w n s c p src_file u s e r n a m e @ host: dest_file  expect {  “(yes/no)?”     {      send “yes\n”      expect “*assword:” { send “ password\n”}
}
“*assword:”
{
send “$password\n”
}
}
expect “100%”

expect eof

chmod +x expect_scp

二.调用与执行scp各文件

vim scp.sh


!/bin/sh

list_file= 1 s r c f i l e = 2
dest_file= 3 c a t list_file | while read line
do
host_ip=echo $line | awk '{print $1}'
username=echo $line | awk '{print $2}'
password=echo $line | awk '{print $3}'
echo “ h o s t i p . / e x p e c t s c p host_ip u s e r n a m e password s r c f i l e dest_file

done

chmod +x scp.sh

三.远程信息文件

vim passwd.txt


192.168.0.100 root redhat

四.总执行脚本

vim all_scp.sh


bash /root/scp.sh /root/passwd.txt 本地源文件路径 目标文件路径

………………….可以很多scp

chmod +x all_scp.sh

**

expect_ssh

**

远程自动化执行脚本

1.实现远程执行动作脚本

vim ssh.sh

!/usr/bin/expect -f

set ipaddress [lindex $argv 0]

set passwd [lindex $argv 1]

set timeout 5

spawn ssh root@$ipaddress //这里主要是 @ 前的用户,是远程主机的用户,我这里全是 root

expect {

“yes/no” { send “yes\r”;exp_continue }

“password:” { send “$passwd\r” }

}

expect “from

send “mkdir /tmp/wml\r” //这是远程执行命令,可以很多条
send “touch /tmp/wml/www\r”

send “exit\r”

expect {

“?assword:” {

send “$PASSWORD\r”

exp_continue

}

}

2.调用执行动作与密码信息脚本,也是总执行脚本

vim wml.sh

!/bin/bash

for i in awk '{print $1}' passwd.txt

do

j=awk -v I="$i" '{if(I==$1)print $2}' passwd.txt

expect /root/ssh.sh i j #执行动作脚本

done

3.远程IP与密码文件

vim passwd.txt

192.168.0.102 redhat
192.168.0.104 redhat
192.168.0.106 redhat

**

expect_scp_ssh

**

【 expect批量自动 《分发文件》 & 《执行文件》 文件 】

注意:1. 所有脚本必须在同一目录下编辑执行,否则不会成功
2. 红色标记为主要改动的地方

一.分发文件

1.远程登陆脚本

mkdir -p /root/auto/

cd /root/auto/

vim scp_login.sh // 此脚本一般情况下,不需要改动


!/usr/bin/expect

set timeout 10
set host [lindex a r g v 0 ] s e t u s e r n a m e [ l i n d e x argv 1]
set password [lindex a r g v 2 ] s e t s r c f i l e [ l i n d e x argv 3]
set dest_file [lindex a r g v 4 ] s p a w n s c p src_file u s e r n a m e @ host: dest_file  expect {  “(yes/no)?”     {      send “yes\n”      expect “*assword:” { send “ password\n”}
}
“*assword:”
{
send “$password\n”
}
}
expect “100%”

expect eof

  1. 分发调用脚本

vim scp_executed.sh // 此脚本中,红色为上面登陆文件


!/bin/sh

list_file= 1 s r c f i l e = 2
dest_file= 3 c a t list_file | while read line
do
host_ip=echo $line | awk '{print $1}'
username=echo $line | awk '{print $2}'
password=echo $line | awk '{print $3}'
echo “ h o s t i p / r o o t / a u t o / s c p l o g i n . s h host_ip u s e r n a m e password s r c f i l e dest_file

done

  1. 远程主机密码文件

vim scp_passwd.sh // 此文件格式:IP 用户名 密码


192.168.0.100 root redhat
192.168.0.104 root redhat

192.168.0.106 root redhat

4.总执行scp脚本

vim scp_all.sh // 此脚本格式:调用文件 密码文件 源文件目录 目标目录


/root/auto/scp_executed.sh /root/auto/scp_passwd.sh /root/iptables.sh /root/

/root/auto/scp_executed.sh /root/auto/scp_passwd.sh 本地源文件路径 目标文件路径

二.执行文件

1.远程登陆脚本

vim ssh_login.sh


!/usr/bin/expect -f

set ipaddress [lindex a r g v 0 ] s e t p a s s w d [ l i n d e x argv 1]
set timeout 5
spawn ssh root@ ipaddress  expect {  “yes/no” { send “yes\r”;exp_continue }  “password:” { send “ passwd\r” }
}
expect “from
send “/root/iptables.sh\r”

send “exit\r”

expect {
“?assword:” {
send “$PASSWORD\r”
exp_continue
}

}

                                                    // 上面脚本红色解析:set timeout 5     //在远程主机执行时,停顿的秒数,可以调整
                                                                        root            //本地主机的身份,可以是其它用户
                                                                        /root/iptables.sh   //远程主机上,执行的动作,可以更多
  1. 远程主机密码文件

vim ssh_passwd.sh // 此脚本格式:IP 用户名 密码


192.168.0.100 redhat
192.168.0.104 redhat

192.168.0.106 redhat

3.总执行ssh文件

vim ssh_all.sh // 前两个红色标记为ssh的密码文件,后一个是ssh的登陆文件


!/bin/bash

for i in awk '{print $1}' "/root/auto/ssh_passwd.sh"
do
j=awk -v I="$i" '{if(I==$1)print $2}' "/root/auto/ssh_passwd.sh"
expect /root/auto/ssh_login.sh i j

done

三.结合

vim all_scp_ssh


/root/auto/scp_all.sh

/root/auto/ssh_all.sh

chmod +x /root/auto -R

/root/auto/all_scp_ssh

猜你喜欢

转载自blog.csdn.net/wangminglong1989/article/details/81508848