expect讲解

expect可以让我们实现自动登录远程机器,并且可以实现自动远程执行命令。当然若是使用不带密码的密钥验证同样可以实现自动登录和自动远程执行命令。但当不能使用密钥验证的时候,我们就没有办法了。所以,这时候只要知道对方机器的账号和密码就可以通过expect脚本实现登录和远程命令。

使用expect之前,需要先安装expect:

a、安装expect

yum install -y expect 

一、自动登陆脚本

vim 1.expect

#! /usr/bin/expect

set host "10.10.13.247"          #远程登陆主机

set passwd "abc.123"             #密码

spawn ssh  root@$host           #远程登陆

expect {                     #判断出现yes/no

"yes/no" { send "yes\r"; exp_continue} #发送yes

"assword:" { send "$passwd\r" }      #发送密码

}

interact

2、添加可执行权限

chmod a+x 1.expect 

3、执行

./1.expect 

spawn ssh [email protected]

The authenticity of host '10.10.13.247 (10.10.13.247)' can't be established.

RSA key fingerprint is 8d:5a:2e:8c:ac:a0:02:c2:46:ba:db:ec:2e:eb:ce:68.

Are you sure you want to continue connecting (yes/no)? yes

Warning: Permanently added '10.10.13.247' (RSA) to the list of known hosts.

[email protected]'s password: 

Last login: Fri Jun 17 21:05:57 2016 from win10.benco.com.cn


二、登陆后执行命令再退出脚本

#!/usr/bin/expect

set user "root"

set passwd "123456"


spawn ssh [email protected]


expect {

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

"password:" { send "$passwd\r" }

}

expect "]*"                   #]*表示判断登陆后的字符是]*

send "touch /tmp/12.txt\r"         #表示根据上上判断输入命令

expect "]*"

send "echo 1212 > /tmp/12.txt\r"

expect "]*"

send "exit\r"

三、传递参数脚本

#!/usr/bin/expect

set user [lindex $argv 0]         #定义第一个参数,即user

set host [lindex $argv 1]         #定义第二个参数,即host

set passwd "abc.123"

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"

./3.expect root 10.10.13.247 w

四、同步文件脚本

#!/usr/bin/expect

set passwd "123456"

spawn rsync -av [email protected]:/tmp/12.txt /tmp/ #执行同步命令

expect {

"yes/no" { send "yes\r"}

"password:" { send "$passwd\r" }

}

expect eof   #执行同步命令后结束

#将10.10.13.247上/tmp目录下的12.txt同步到本地/tmp目录

#如果本地和远程机器上没有rsync命令则会报错

五、指定host和要同步的文件


#!/usr/bin/expect

set passwd "abc.123"

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

#如果要同步的远程主机不止一台可以把ip和文件列表写下一个文件,使用for循环:

for ip in `cat /tmp/ip.txt`; do ./5.expect $ip $file;done

六、文件分发系统的实现(文件清单同步)

a. 需求背景
对于大公司而言,肯定时不时会有网站或者配置文件更新,而且使用的机器肯定也是好多台,少则几台,多则几十甚至上百台。所以,自动同步文件是至关重要的。

b. 实现思路
首先要有一台模板机器,把要分发的文件准备好,然后只要使用expect脚本批量把需要同步的文件分发到目标机器即可。

c. 核心命令
rsync -av --files-from=list.txt  /  root@host:/
1、创建同步脚本

1、创建expect脚本

vim rsync.expect

#!/usr/bin/expect

set passwd "abc.123"

set host [lindex $argv 0]

set file [lindex $argv 1]

spawn rsync -av --files-from=$file / root@$host:/

expect {

"yes/no" { send "yes\r"}

"password:" { send "$passwd\r" }

}

expect eof

#必须保证每台机器的账号密码都一样

2、创建循环脚本

vim rsync.sh

#!/bin/bash

for ip in `cat ip.list`

do

    echo $ip

    ./rsync.expect $ip list.txt

done

3、创建ip清单和文件清单

vim ip.list

10.10.13.247

vim list.txt

/tmp/12.txt

4、执行

chmod a+x rsync.sh rsync.expect 

#修改下/tmp/12.txt添加内容后执行

sh rsync.sh

#发现10.10.13.247内容也修改,其实是直接把本机的/tmp/12.txt同步到13.247的/tmp目录并覆盖了

#注意两个脚本要有执行权限要在同一个目录

七、命令同步执行

1、创建expect脚本

#!/usr/bin/expect

set host [lindex $argv 0]

set passwd "abc.123"

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、命令执行脚本

#!/bin/bash

for ip in `cat ip.list`

do

    echo $ip

    ./exe.expect $ip "w;free -m;ls /tmp"

done

#注意两个脚本要有执行权限要在同一个目录