非交互expect
介绍expect
认识expect
expect是一个自动化交互套件,主要应用于执行命令和程序时,系统以交互形式要求输入指定字符串,实现交互通信。
expect自动交互流程
spawn启动指定进程---expect获取指定关键字---send向指定程序发送指定字符---执行完成退出.
expect常用命令总结
spawn 交互程序开始后面跟命令或者指定程序
expect 获取匹配信息匹配成功则执行expect后面的程序动作
send exp_send 用于发送指定的字符串信息
exp_continue 在expect中多次匹配就需要用到
send_user 用来打印输出 相当于shell中的echo
exit 退出expect脚本
eof expect执行结束 退出
set 定义变量
puts 输出变量
set timeout 设置超时时间
安装expect
[root@hadoop04 ~]# yum -y install expect
编写expect脚本
初始版
[root@hadoop04 shell_expect]# vim expect_ssh01.sh
#!/usr/bin/expect
#开启一个会话
spawn ssh alice@172.22.34.19
expect {
"yes/no" { send "yes
";exp_continue }
"password" { send "5tgb^YHN
" };
}
# 停留在远程机器的界面
interact
[root@hadoop04 shell_expect]# expect expect_ssh01.sh
改进版1
增加变量定义、变量引用
[root@hadoop04 shell_expect]# vim expect_ssh02.sh
#!/usr/bin/expect
# 定义变量
set ip 172.22.34.19
set user alice
set password 5tgb^YHN
set timeout 5
#开启一个会话
spawn ssh ${user}@${ip}
expect {
"yes/no" { send "yes
";exp_continue }
"password" { send "${password}
" };
}
interact
[root@hadoop04 shell_expect]# expect expect_ssh02.sh
spawn ssh alice@172.22.34.19
alice@172.22.34.19's password:
Last login: Tue Dec 10 22:00:03 2019 from 172.22.34.20
[alice@hadoop03 ~]$
改进版2
位置参数作为变量值赋值给变量,进入到远程机器后,创建测试文件test.txt,查看当前目录,退出远程机器,结束expect
[root@hadoop04 shell_expect]# vim expect_ssh03.sh
#!/usr/bin/expect
# 定义变量
# 第一个位置参数
set ip [lindex $argv 0]
set user alice
set password 5tgb^YHN
set timeout 5
#开启一个会话
spawn ssh ${user}@${ip}
expect {
"yes/no" { send "yes
";exp_continue }
"password" { send "${password}
" };
}
#interact
expect "$"
send "touch test.txt
"
send "ls
"
send "pwd
"
send "exit
"
# 结束expect
expect eof
# 执行脚本
[root@hadoop04 shell_expect]# expect expect_ssh03.sh 172.22.34.19
spawn ssh alice@172.22.34.19
alice@172.22.34.19's password:
Last login: Tue Dec 10 21:59:53 2019 from 172.22.34.20
[alice@hadoop03 ~]$ touch test.txt
[alice@hadoop03 ~]$ ls
test.txt
[alice@hadoop03 ~]$ pwd
/home/alice
[alice@hadoop03 ~]$ exit
logout
Connection to 172.22.34.19 closed.
改进版3
批量主机推送公钥推送
#!/usr/bin/bash
ip_file=ip.txt
password=feidee.com
>${ip_file}
for i in {16..19}
do
{
ip=172.22.34.${i}
ping -c1 -W1 ${ip} &> /dev/null
if [ $? -eq 0 ];then
echo "${ip}" >> ${ip_file}
# 使用expect推送公钥
/usr/bin/expect <<-EOF
spawn ssh-copy-id ${ip}
expect {
"yes/no" { send "yes
"; exp_continue }
"password:" { send "${password}
" }
}
expect eof
EOF
fi
}&
done
wait
echo "All finish..."
改进版4
批量主机推送公钥推送,添加兼容:expect未安装时先安装expect,密钥未创建时先创建密钥
#!/usr/bin/bash
ip_file=ip.txt
password=feidee.com
>${ip_file}
# 检查expect是否安装
rpm -q expect &> /dev/null
if [ $? -eq 0 ];then
echo "正在安装expect,请稍候..."
yum -y install expect &> /dev/null && echo "expect 安装完成."
fi
# 检查密钥是否存在
if [ ! -f ~/.ssh/id_rsa ];then
echo "正在创建密钥,请稍后..."
# 非交互式的ssh-keygen
ssh-keygen -P "" -f ~/.ssh/id_rsa &> /dev/null && echo "密钥创建成功"
fi
for i in {16..19}
do
{
ip=172.22.34.${i}
ping -c1 -W1 ${ip} &> /dev/null
if [ $? -eq 0 ];then
echo "${ip}" >> ${ip_file}
# 使用expect推送公钥
/usr/bin/expect <<-EOF
spawn ssh-copy-id ${ip}
expect {
"yes/no" { send "yes
"; exp_continue }
"password:" { send "${password}
" }
}
expect eof
EOF
fi
}&
done
wait
echo "All finish..."