1.分发系统介绍
-
expect:一个实现自动交互功能的软件套件,基于Tcl的一种脚本语言,具有简单的语法
-
功 能 :实现自动登录远程机器,并自动执行命令;和shell脚本结合,可以实现完全自动化
-
注 意:若是使用不带密码的密钥验证同样可以实现自动登录和自动远程执行命令。但当不能使用密钥验证的时候,我们就没有办法了。所以,这时只知道对方机器的账号和密码可以通过expect脚本实现登录和远程命令
2.expect脚本远程登录
1).首先进行检查有没有安装expect这个安装包,没有安装就直接进行安装 yum install -y expect
2).在/usr/local/sbin/下面创建一个脚本文件,取名为expect,并在脚本内容里面增加以下内容
#! /usr/bin/expect
set host "192.168.126.129" //设置连接主机
set passwd "1" //设置密码
spawn ssh root@$host //执行命令
expect {
"yes/no" { send "yes\r"; exp_continue} //假如第一次登陆,需要yse,然后回车,继续执行
"password:" { send "$passwd\r" } //输入密码
}
interact
代码解释:
- #! /usr/bin/expect 这一行告诉操作系统脚本里的代码使用那一个shell来执行
- 在expect下 定义变量,用 set,比如 定义变量a为1 :set a 1
- expect 使用expect语句进行交互
- \r表示回车
- exp_continue 表示继续 \r 表示换行 interact 继续停留在这台机器,不退出
- interact表示继续交互
如果执行脚本发现出错了,因为yes/no 可以把/root/.ssh/known_hosts里面的文件给删除掉清空之后再进行执行脚本
3).给脚本一个755权限并执行脚本
3.expect脚本远程执行命令
1).再次编辑一个文件增加以下内容,并给予755权限·,然后执行2.expect
#! /usr/bin/expect
set user "root"
set passwd "1"
spawn ssh $user@192.168.126.129
expect {
"yes/no" { send "yes\r"; exp_continue}
"password:" { send "$passwd\r" }
}
expect "]*"
send "touch /tmp/12.txt\r"
expect "]*"
send "echo 1122 > /tmp/12.txt\r"
expect "]*"
send "exit\r"
2).在我们刚才远程登录的机器上进行查看我们刚才远程登录的命令看看有没有执行
4.expect脚本传递参数
expect脚本可以接受从bash传递过来的参数.可以使用[lindex $argv n]获得,n从0开始,分别表示第一个,第二个,第三个….参数
1).下面编辑一个文件并进行实验,文件内容如下
#!/usr/bin/expect
set user [lindex $argv 0] //第一个参数
set host [lindex $argv 1] //第二个参数
set passwd "1"
set cm [lindex $argv 2] //第三参数
spawn ssh $user@$host
expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r" }
}
expect "]*"
send "$cm\r"
expect "]*"
send "exit\r"
2).执行脚本并进行查看,命令之间用;号进行分隔开
5.expect脚本同步文件
1).先进行编辑一个文件并给予755权限
#!/usr/bin/expect
set passwd "1"
spawn rsync -av root@192.168.126.129:/tmp/12.txt /tmp/
expect {
"yes/no" { send "yes\r"}
"password:" { send $passwd\r}
}
expect eof //结束expect匹配。
expect eof 语句解释:
- spawn执行的命令结果,会被expect捕捉到。因为spawn会启动一个进程,只有这个进程的相关信息才会被捕捉到,主要包括:标准输入的提示信息,eof和timeout
- 在这里eof是必须去匹配的,在spawn进程结束后会向expect发送eof,如果expect没有匹配,那么会立即退出远程登录,即操作失败
2).执行编辑的文件
6.expect脚本指定host和要同步的文件
1).编辑指定host要同步的文件的expect脚本
#!/usr/bin/expect
set passwd "1"
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
2).授权并进行测试
注意:
- 1、这里要同步的文件,必要要写绝对路径;
- 2、备份的时候,注意时间限制;可以设定 set timeout 定义超时时间(单位为 秒) -1 为永远不超时
7.构建文件分发系统
-
实现思路:
首先要有一台模板机器,把要分发的文件准备好,然后只要使用expect脚本批量把需要同步的文件分发到目标机器即可
-
核心命令:
rsync -av --files-from=list.txt / root@host:/ 注意:这里的都是根目录
使用rsync 的 --files参数,可以实现调用文件里面的列表,进行多个文件远程传输,进而实现文件分发文件分发系统的实现
1).编写rsync.expect 脚本
#!/usr/bin/expect
set passwd "1"
set host [lindex $argv 0]
set file [lindex $argv 1]
spawn rsync -avR --files-from=$file / root@$host:/
expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r" }
}
expect eof
2.因为实现分发系统,肯定是因为需要分发的机器数量过大,所以,定义好了 文件 的 list 列表文件以后, 还需要配置 ip 的列表文件
3.创建file.list 需要同步文件的列表
4.创建一个rsync的shell脚本,脚本的目的:遍历所有的server和list中的文件可以同步到每台服务器
5.授权rsync.expect脚本,并测试
8.批量远程执行命令
当同步完代码后有可能需要批量地重启服务,因此还需要批量远程执行命令,类似于自动化。 这里是用expect编写执行命令的脚本并用shell脚本来批量调用它
1).先创建一个文件内容如下
#!/usr/bin/expect
set host [lindex $argv 0]
set passwd "1"
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"
2.再新建exe.sh的shell脚本,用来调用exe.expect脚本
#!/bin/bash
for ip in `cat /tmp/ip.list` //循环执行ip.list,注意ip清单是上个试验的;
do
echo $ip
./exe.expect $ip "w;free -m;ls /tmp" //调用exe的expect脚本,并传递参数;
done
3.给exe.expect可执行权,并进行测试