27.分发系统介绍--expect
expect是一种脚本语言,可以实现传输文件,实现远程执行命令,上线代码(将开发人员开发的代码发送到服务器上去),不需输入密码,针对多终端,多访问量,多接口的环境,可以用分发系统,对每段时间更新的代码分别发布到终端上
- 首先要准备一台模板机器,有最新的代码
- 要知道所有设备的IP
- 要知道这些用户的密码
- expect脚本借助RSVNC推送脚本到这些机器上去
28.expect脚本远程登录
- 示例一:
yum install -y expect
自动远程登录
#! /usr/bin/expect
set host "192.168.0.12" #expect中定义变量
set passwd "12345678" #expect中定义变量
spawn ssh root@$host
expect {
"yes/no" { send "yes\r"; exp_continue} #第一次使用ssh会提示是否登陆,\r为回车
"assword:" { send "$passwd\r" } #截取assword:,如果有,发送¥passwd
}
interact #表示需要停留在远程的机器上,不需要退出,还有一个expect eof用法同interact,表示停留10秒钟退出
####################执行结果:####################
[root@localhost expect-test]# ifconfig | grep -A1 "eth0"| awk '{print $2}'|awk -F':' '{print $2}'
192.168.0.11
[root@localhost expect-test]# ./test.expect
spawn ssh root@192.168.0.12
root@192.168.0.12's password:
Last login: Sat Dec 29 07:33:35 2018 from 192.168.0.11
[root@localhost ~]# ifconfig | grep -A1 "eth0"| awk '{print $2}'|awk -F':' '{print $2}'
192.168.0.12
[root@localhost ~]#
29.expect脚本远程执行命令
yum install -y expect
自动远程登录
#! /usr/bin/expect
set host "192.168.0.12" #expect中定义变量
set passwd "12345678" #expect中定义变量
spawn ssh root@$host
expect {
"yes/no" { send "yes\r"; exp_continue} #第一次使用ssh会提示是否登陆,\r为回车
"assword:" { send "$passwd\r" } #截取assword:,如果有,发送¥passwd
}
expect "]*" #当遇到]#或者]$时(登陆后的主机名显示),执行下边的内容
send "touch /tmp/expect-test\r"
expect "]*"
send "echo Hello,world! > /tmp/expect-test\r"
expect "]*"
send "exit\r"
执行结果:
192.168.0.11:
[root@localhost expect-test]# ./test1.expect
spawn ssh root@192.168.0.12
root@192.168.0.12's password:
Last login: Sat Dec 29 07:35:11 2018 from 192.168.0.11
[root@localhost ~]# touch /tmp/expect-test
[root@localhost ~]# echo Hello,world! > /tmp/expect-test
192.168.0.12:
[root@localhost ~]# ifconfig | grep -A1 'eth0' | awk '{print $2}'| awk -F ':' '{print $2}'
192.168.0.12
[root@localhost ~]# cat /tmp/expect-test
Hello,world!
[root@localhost ~]#
30.expect脚本传递参数
#!/usr/bin/expect
set user [lindex $argv 0] #该句是引用参数的值,[lindex $argy 0]是第一个参数,把第一个参数的值赋给user
set host [lindex $argv 1] #
set passwd "123456"
set cm [lindex $argv 2] #cm是第三个参数,要执行的命令
spawn ssh $user@$host
expect {
"yes/no" {send "yes\r"}
"password:" {send "$passwd\r"}
}
expect "]*"
send "$cm\r"
expect "]*"
send "exit\r"
执行结果:
[root@localhost expect-test]# ./test2.expect root 192.168.0.12 ls #执行多个命令时,eg:“ls;w;vmstat 1”,执行vmstat 1这样的命令,如果要长时间执行可以在定义该变量下加一行“set timeout -1”,-1是永久不超时,其他按秒计
spawn ssh root@192.168.0.12
root@192.168.0.12's password:
Last login: Sat Dec 29 10:09:45 2018 from 192.168.0.11
[root@localhost ~]# ls
anaconda-ks.cfg install.log install.log.syslog
[root@localhost ~]# [root@localhost expect-test]#
31.expect脚本同步文件
#!/usr/bin/expect
set passwd "1qaz@WSX@123"
spawn rsync -av root@192.168.1.12:/root/expect_tran /usr/local/sbin/expect-test/
expect {
"yes/no" {send "yes\r"}
"password:" {send "$passwd\r"}
}
expect eof #如果没有此句,脚本登陆后就会退出,无法传输文件
执行结果:
[root@localhost expect-test]# ./transport.expect
spawn rsync -av root@192.168.1.12:/root/expect_tran /usr/local/sbin/expect-test/
root@192.168.1.12's password:
receiving incremental file list
expect_tran
sent 30 bytes received 80 bytes 73.33 bytes/sec
total size is 0 speedup is 0.00
[root@localhost expect-test]#
如果注释掉expect eof结果:
[root@localhost expect-test]# ./transport.expect
spawn rsync -av root@192.168.1.12:/root/expect_tran /usr/local/sbin/expect-test/
root@192.168.1.12's password:
[root@localhost expect-test]#
32.expect脚本指定host和要同步的文件
#!/usr/bin/expect
[root@localhost expect-test]# cat file.expect
#!/usr/bin/expect
set passwd "123456"
set host [lindex $argv 0]
set file [lindex $argv 1]
spawn rsync -av $file root@$host:$file #从本机同步到对方
expect {
"yes/no" { send "yes\r" }
"password:" { send "$passwd\r" }
}
expect eof
[root@localhost expect-test]#
执行结果:
[root@localhost expect-test]# ./file.expect 192.168.1.12 /root/file.expert
spawn rsync -av /root/file.expert root@192.168.1.12:/root/file.expert
root@192.168.1.12's password:
sending incremental file list
file.expert
sent 75 bytes received 31 bytes 212.00 bytes/sec
total size is 0 speedup is 0.00
33.构建文件分发系统
文件分发系统的实现: 前提:所需同步的设备的用户名密码都是一样的,或者使用密钥认证
rsync.expect内容
#!/usr/bin/expect
set passwd "123456"
set host [lindex $argv 0]
set file [lindex $argv 1] #这里的file是一个文件列表
spawn rsync -avR --files-from=$file / root@$host:/ #该句为核心目录,要保证对方的主机上要有相同的路径,没有则加R选项
expect {
“yes/no” {send "yes\r"}
"password:" {send "$passwd\r"}
}
expect eof
ip.list #列表内容,用于向各个主机推送信息,eg:
[root@localhost expect-test]# cat /tmp/ip.list
192.168.1.12
192.168.1.13
......
file.list #文件列表,需要同步的文件目录,是绝对路径eg:
[root@localhost expect-test]# cat /tmp/file.list
/root/file.expert
/root/1.txt
/tmp/12.txt
rsync.sh #是文件遍历IP地址,发送文件
#!/bin/bash
[root@localhost expect-test]# cat rsync.sh
#!/bin/bash
for ip in `cat /tmp/ip.list`
do
echo $ip
./rsync.expect $ip /tmp/file.list
done
执行结果:
[root@localhost expect-test]# sh -x rsync.sh
++ cat /tmp/ip.list
+ for ip in '`cat /tmp/ip.list`'
+ echo 192.168.1.12
192.168.1.12
+ ./rsync.expect 192.168.1.12 /tmp/file.list
spawn rsync -av --files-from=/tmp/file.list / root@192.168.1.12:/
root@192.168.1.12's password:
building file list ... done
root/
root/1.txt
tmp/
tmp/12.txt
sent 193 bytes received 56 bytes 498.00 bytes/sec
total size is 0 speedup is 0.00
34.批量远程执行命令
命令批量执行:三个文件:expect文件,脚本文件和ip.list
exe.expect
[root@localhost expect-test]# cat exe.expect
#!/usr/bin/expect
set host [lindex $argv 0]
set passwd "123456"
set cm [lindex $argv 1]
spawn ssh root@$host
expect {
"yes/no" { send "yes\r" }
"password:" { send "$passwd\r" }
}
expect "]*"
send "$cm\r"
expect "]*"
send "exit\r"
[root@localhost expect-test]# cat exe.sh
#!/bin/bash
for ip in `cat /tmp/ip.list`
do
./exe.expect $ip hostname
done
[root@localhost expect-test]# cat /tmp/ip.list
192.168.1.12
192.168.1.13
执行结果:
[root@localhost expect-test]# sh -x exe.sh
++ cat /tmp/ip.list
+ for ip in '`cat /tmp/ip.list`'
+ ./exe.expect 192.168.1.12 hostname
spawn ssh root@192.168.1.12
root@192.168.1.12's password:
Last login: Sat Dec 29 16:30:29 2018 from 192.168.1.11
[root@localhost ~]# hostname #批量执行的命令
localhost.localdomain
[root@localhost ~]# + for ip in '`cat /tmp/ip.list`'
+ ./exe.expect 192.168.1.13 hostname
spawn ssh root@192.168.1.13
ssh: connect to host 192.168.1.13 port 22: No route to host #s192.168.1.13本身不存在
expect: spawn id exp4 not open
while executing
"expect "]*""
(file "./exe.expect" line 10)
[root@localhost expect-test]#