expect是一个免费的编程工具语言,用来实现自动和交互式任务通信的编程工具语言。
expect 安装
源码包安装需要先
Tcl
库,因为expect是在Tcl
基础上创建起来的,所以这里我就不用源码包安装了,直接用yum安装
## expect 在base源,这里我用的是阿里云的YUM源,有base源可以忽略 [root@Shell ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo [root@Shell ~]# yum makecache ## 用yum安装expect [root@Shell ~]# yum install expect -y
expect基础应用
- expect脚本一般以
#!/usr/bin/expect
开头 - expect脚本常以.exp或者.ex结束。
- expect主要命令
- spawn 新建一个由expect控制的进程
- expect 等待接受进程返回的字符串,直到超时时间
- send 发送字符串给expect控制的进程
- set 设定变量
- exp_continue 重新从当前expect块的开始执行
- [lindex 1
- [lindex 2
- set timeout -1 设置超时时间为永远等待
- set timeout 30 设置超时时间为30秒
- interact 保持当前状态,并把控制权交给用户
- expect eof 等待spawn进程结束后退出
expect 实现用ssh密码交互登陆
#!/usr/bin/expect ## 设定变量password等于123.com set password 123.com ## 新建一个进程,执行ssh命令 spawn ssh root@192.168.1.2 expect { ## 当询问 "yes/no" { send "yes\r"; exp_continue } "password" { send "$password\r" } } interact
expect 进行参数传递,ssh登陆之后创建用户 yunxiang 并设置密码
#!/usr/bin/expect ## 位置参数传递 set ip [lindex $argv 0] set user root set password 123.com set passwd 456.com ## 响应等待5秒,超时进入下一条 set timeout 5 spawn ssh $user@$ip expect { "yes/no" { send "yes\r"; exp_continue } "password" { send "$password\r" }; } # 当出现 # 号符执行如下命令 expect "#" send "useradd yunxiang\r" send "passwd yunxiang\r" expect { "New password:" { send "$passwd\r"; exp_continue } "Retype new password:" { send "$passwd\r" } } send "exit\r" ## 都执行完了就退出 expect eof
最后用
Shell+expect
批量获取在线主机, 进行秘钥批量分发
#!/usr/bin/bash password="123.com" ## 清空ip.txt文件 >ip.txt ## 使用循环把ping通ip放到ip.txt文件中 for i in {2..10} do ip=192.168.1.$i { ping -c1 -W1 $ip &>/dev/null if [ $? -eq 0 ];then echo "$ip" >> ip.txt fi }& done ## 生成对应的密钥 if [ ! -f ~/.ssh/id_rsa ];then ssh-keygen -P "" -f ~/.ssh/id_rsa fi ## 把ip.txt文件以每行循环 while read line do ## 调用expect /usr/bin/expect <<-EOF set timeout 5 spawn ssh-copy-id $line -f expect { "yes/no" { send "yes\r"; exp_continue } "password:" { send "$password\r" } } expect eof EOF done<ip.txt
#!/bin/bash password="123" > ip.txt if [ ! -f ~/.ssh/id_rsa ] then ssh-key-id -P "" -f ~/.ssh/id_rsa fi for i in {2..10} do ip=192.168.1.$i ping -c 1 -W 1 $ip > /dev/null if [ $? -eq 0 ] then /usr/bin/expect <<-EOF set timeout 5 spawn ssh-copy-id $ip -f expect { "yes/no" { send "yes\r"; exp_continue } "password" { send "$password\r" } } expect eof EOF >> ip.txt fi done