需求:开发人员开发的代码发布到线上环境中(其实后面用到jenkins才是真正的98k)
expect可以让我们实现自动登录远程机器,并且可以实现自动远程执行命令。当然若是使用不带密码的密钥验证同样可以实现自动登录和自动远程执行命令。但当不能使用密钥验证的时候,我们就没有办法了。所以,这时候只要知道对方机器的账号和密码就可以通过expect脚本实现登录和远程命令。
分发准备:模板脚本、服务器ip、用户名、密码、expect脚本
yum install -y expect
expect脚本登录机器:
vim 1.expect#!/usr/bin/expect set host "192.168.133.132" #连接到主机set passwd "123456" #密码spawn ssh root@$host #spawn调用shell命令ssh(登录),“set host”和“set passwd”为expect定义的两个变量expect {"yes/no" { send "yes\r"; exp_continue} #ssh首次远程登录一台主机是会提示yes/no,吧yes发送过去;"\r“表示回车"password:" { send "$passwd\r" } #如果提示passwd需要把密码发送过去,用户交互,"\r“表示回车}interact#interact的作用是停留在远程机器上,不退出#脚本结束符号:expect eof——执行结束后暂停几秒钟后退出#如果不加任何结束符号,命令执行完后马上退出
注意的是需要755权限,即chmod a+x 1.expect
执行该脚本使用:./1.expect
expect脚本远程执行命令:
vim 2.expect#!/usr/bin/expectset user "root"set passwd "123456"spawn ssh $user@192.168.133.132expect {"yes/no" { send "yes\r"; exp_continue}"password:" { send "$passwd\r" }}expect "]*" #匹配到“]”指的是登录成功后左边的用户信息的右括号,意思是登录成功后执行下面的命令send "touch /tmp/12.txt\r" "\r“表示回车,然后又匹配到左边的的用户信息括号expect "]*"send "echo 1212 > /tmp/12.txt\r" "\r“表示回车,然后又匹配到左边的的用户信息括号expect "]*"send "exit\r"
expect脚本传递参数:
vim 3.expect#!/usr/bin/expect #调用内部参数,用户名ip密码,在执行的时候直接调用set user [lindex $argv 0]set host [lindex $argv 1]set passwd "123456"set cm [lindex $argv 2]#这个是第三个参数,就是要执行的命令,比如lsspawn ssh $user@$hostexpect {"yes/no" { send "yes\r"}"password:" { send "$passwd\r" }}expect "]*"send "$cm\r"expect "]*"send "exit\r"#如果需要执行多条命令使用;分隔和双引号,比如“ls;w;cat 1.txt”#expect存在超时时间,不适合运行vmstart这种命令#如果想要修改超时时间,在send "$cm\r"下一行加上set timeout -1 永久不超时set timeout 5 五秒时间推出
expect脚本同步文件:
vim 4.expect#!/usr/bin/expectset passwd "123456"spawn rsync -av root@192.168.204.137:/tmp/12.txt /tmp/#把远程机器上的12.txt同步到本机expect {"yes/no" { send "yes\r"}"password:" { send "$passwd\r" }}expect eof#脚本结束符号:expect eof——执行结束后暂停几秒钟后退出
expect脚本指定host和要同步的文件:
vim 5.expect#!/usr/bin/expectset passwd "123456"set host [lindex $argv 0]set file [lindex $argv 1]spawn rsync -av $file root@$host:$file #file写绝对路径expect {"yes/no" { send "yes\r"}"password:" { send "$passwd\r" }}expect eofchmod a+x 5.expecttouch 1.txt./5.expect 192.168.133.132 "/tmp/1.txt"
构建文件分发系统
这里思路为首先写expect脚本,然后提供参数,最后使用shell脚本实现分发功能
#第一步写expect脚本,最后shell也是调用到了这里来实现功能vim rsync.expect#!/usr/bin/expectset passwd "123456"set host [lindex $argv 0]set file [lindex $argv 1]#这里指的对应IP和文件列表,在最后的shell脚本中来实现spawn rsync -av --files-from=$file / root@$host:/#如果不能保证对方机器有相同路径加上-avRexpect {"yes/no" { send "yes\r"}"password:" { send "$passwd\r" }}expect eof
#第二步提供要被传送的文件的集合,也就是exoect脚本的第二个参数filevim list.txt/root/shell/1.sh......#该文件下可添加多个文件,这个就是要传送的文件了
#第三步定义对应ip的内容,也就是expect的host参数vim iplist.txt192.168.133.132192.168.133.133......#此处IP(主机)密码要和rsync.expect脚本中一致。为了避免密码泄露的风险,可以使用密钥认证的方法
#最后shell脚本实现功能vim rsync.sh#!/bin/bashfor ip in `cat iplist.txt`do echo $ip ./rsync.expect $ip list.txtdone#该脚本作用是遍历文件和ip列表
批量远程执行命令
#第一步expect脚本调用host和具体的命令$cmvim exe.expect#!/usr/bin/expectset host [lindex $argv 0] #第一个变量set passwd "123456"set cm [lindex $argv 1] #第二个变量spawn ssh root@$hostexpect {"yes/no" { send "yes\r"}"password:" { send "$passwd\r" }}expect "]*"send "$cm\r"expect "]*"send "exit\r"#该脚本作用是远程执行命令chmod a+x exe.expect
#然后定义shell脚本,指定ip和使用的命令#执行此脚本的目的是一次性多台机器执行相同命令,所有shell中定义需执行的命令vim exe.sh#!/bin/bashfor ip in `cat iplist.txt`do echo $ip ./exe.expect $ip "w;free -m;ls /tmp"done#该脚本的作用是调用iplist.txt文件中的IP和exe.expect脚本