1 安装expect

# ubantu

sudo apt-get install expect

# centos

yum install -y expect

2 expect 用法

# spawn  交互程序开始后面跟命令或者指定程序

# expect 获取匹配信息匹配成功则只需except后面的程序动作

# send exp_send 用于发送指定的字符串信息

# exp_continue 在expectt中多次匹配就需要用到

# send_user 用于打印输出,相当于shell的echo

# exit 退出expect脚本

# eof expect执行结束,退出

# set 定义变量

# puts 输出变量

# set timeout 设置超时时间

# expect {
# "***1" { send "***\r" }
# "***2" { send "***\r" }
#}

# expect {},多行期望,匹配到哪条执行哪条
# 有时执行shell后预期结果是不固定的,有可能是询问是yes/no,有可能是去输入密码,所以可以用expect{}
# 花括号内放多行语句,从上至下匹配,匹配到哪个expect执行哪句。

3 脚本示例 【ssh到远程服务器执行ifconfig命令】

#!/usr/bin/expect
spawn ssh python@192.168.138.137 "ifconfig"
expect "*password"
send "zhang1029\n"
expect eof
# 上面脚本\n可用\r代替

# 输出结果

python@ubuntu:~/zml$ ./test.sh
spawn ssh python@192.168.138.137 ifconfig
python@192.168.138.137's password:
ens33 Link encap:以太网 硬件地址 00:0c:29:45:3b:39
inet 地址:192.168.138.137 广播:192.168.138.255 掩码:255.255.255.0
inet6 地址: fe80::72c6:bd9a:7a8d:9650/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 跃点数:1
接收数据包:101833 错误:0 丢弃:0 过载:0 帧数:0
发送数据包:24583 错误:0 丢弃:0 过载:0 载波:0
碰撞:0 发送队列长度:1000
接收字节:144124195 (144.1 MB) 发送字节:1612687 (1.6 MB)

lo Link encap:本地环回
inet 地址:127.0.0.1 掩码:255.0.0.0
inet6 地址: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 跃点数:1
接收数据包:440 错误:0 丢弃:0 过载:0 帧数:0
发送数据包:440 错误:0 丢弃:0 过载:0 载波:0
碰撞:0 发送队列长度:1000
接收字节:37219 (37.2 KB) 发送字节:37219 (37.2 KB)

4 执行多条语句

#!/usr/bin/expect
spawn sudo su - root
expect "*password*"
send "zhang1029\r"
expect "#*"
send "ls\r"
expect "#*"
send "df -h\r"
send "exit\r"
expect eof



# 输出内容如下
python@ubuntu:~/zml$ ./test2.sh
spawn sudo su - root
[sudo] password for python:
root@ubuntu:~# ls
test.sh
root@ubuntu:~# df -h
文件系统 容量 已用 可用 已用% 挂载点
udev 972M 0 972M 0% /dev
tmpfs 199M 8.9M 190M 5% /run
/dev/sda1 21G 9.0G 11G 47% /
tmpfs 992M 29M 964M 3% /dev/shm
tmpfs 5.0M 4.0K 5.0M 1% /run/lock
tmpfs 992M 0 992M 0% /sys/fs/cgroup
tmpfs 199M 64K 199M 1% /run/user/1000
root@ubuntu:~# exit
注销

 5  创建ssh key,将id_rsa和id_rsa.pub文件分发到各台主机上面

#!/bin/bash

if [ ! -f ~/.ssh/id_rsa ];then
ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa
else
echo "id_rsa has created "
fi

while read line
do
ip=`echo $line | cut -d " " -f 1`
user=`echo $line | cut -d " " -f 2`
passwd=`echo $line | cut -d " " -f 3`
/usr/bin/expect <<-EOF
set timeout 10
spawn ssh-copy-id $user@$ip
expect {
"yes/no" {send "yes\n";exp_continue}
"password" { send $passwd\n}
}
expect "password" { send $passwd\n}
expect eof
EOF
done < host


cat host
192.168.138.137 python zhang1029
192.168.138.137 python zhang1029

执行结果
python@ubuntu:~/.ssh$ ./test3.sh
spawn ssh-copy-id python@192.168.138.137
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
sign_and_send_pubkey: signing failed: agent refused operation
python@192.168.138.137's password:

Number of key(s) added: 1

Now try logging into the machine, with: "ssh 'python@192.168.138.137'"
and check to make sure that only the key(s) you wanted were added.

expect: spawn id exp4 not open
while executing
"expect "
spawn ssh-copy-id python@192.168.138.137
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
sign_and_send_pubkey: signing failed: agent refused operation
python@192.168.138.137's password:

Number of key(s) added: 1

Now try logging into the machine, with: "ssh 'python@192.168.138.137'"
and check to make sure that only the key(s) you wanted were added.

expect: spawn id exp4 not open
while executing
"expect "

#最后报错原因:生成了ssh公钥,并拷贝到了目标机器上,因此,没有等到expect eof是,ssh连接已经关闭了。
#删掉目标机器上的公钥即可。但是不删除的话,每次运行还会出现这个报错,暂时没有搜到更好的解决办法。