转载:shell expect实战实例
shell expect
一个自动化交互的软件,常用场景:在回车后需要输出一些内容
批量传输文件,批量远程命令执行,修改密码,安装软件
一、安装 expect程序
yum -y install expect
二、expect 变量
1、赋值变量
set 变量名 变量值
set ip 192.168.10.3
$ip 引用赋值变量
2、位置变量
[lindex $argv 0] 第1位参数
[lindex $argv 1] 第2位参数
执行时 必须指定两个参数
3、特别注意:
-
expect的脚本,必须赋予执行权限 a+x / +x
-
expect不能用sh来执行,不能用source执行。只可以用 ./路径执行。
三、expect格式
exp_continue:如果后面还有要匹配的参数采用此句表示暂不跳出
\r 确定,回车(表示肯定)
interact 停止在结束位置,什么都不做
expect {
"遇到的内容" { send "传递的参数\r"; exp_continue }
"遇到的第二个内容" { send "传递的参数\r" };
}
#interact 停在当前所处位置
expect eof 结束
四、bash脚本中嵌套expect
expect << EOF
cmd
EOF
或者
/usr/bin/expect << EOF
cmd
EOF
或者
/usr/bin/expect << !
cmd
!
案例1:expect 实现ssh交互式登录
#!/bin/expect
set ip 192.168.10.3
set user root
set passwd 123.com
#spawn 开启一个会话,开启一个指令
spawn ssh $user@$ip
expect {
#如果出现 “yes/no”,则用send传参“yes\r”,\r回车,然后 continue是为没有出现yes时,跳过继续执行一下步。
"yes/no" { send "yes\r"; exp_continue}
"password" {send "$passwd\r"};
}
#停在对端
interact
执行:
expect ./ssh_expect.sh
spawn ssh root@192.168.10.2
root@192.168.10.2’s password:
Last login: Mon Apr 6 16:49:34 2020 from 192.168.10.225
案例2:expect传参 实现ssh交互式登录并执行命令
#!/bin/expect
#传入的第一个参数
set ip [lindex $argv 0]
#传入的第二个参数
set user [lindex $argv 1]
set passwd 123.com
spawn ssh $user@$ip
expect {
"yes/no" { send "yes\r"; exp_continue}
"password" {send "$passwd\r"};
}
#interact,后面不建议再添加其他匹配内容
#到了对端后,匹配root用户的#号,还可以继续执行命令
expect "#"
send "useradd yangyang\r"
send "pwd\r"
send "exit\r"
#expect eof 结束语句
expect eof
执行脚本
[root@localhost shell]# ./ssh_expect.sh 192.168.10.3 root
案例3:expect 实现scp文件传递
#!/bin/expect
#传入一个IP地址的参数
set ip [lindex $argv 0]
set user root
set password 123.com
set timeout 5
spawn scp -r /etc/hosts $user@$ip:/tmp
expect {
"yes/no" { send "yes\r"; exp_continue }
"password" { send "$password\r" };
}
#interact
expect eof
执行脚本
[root@localhost shell]# ./ssh_expect.sh 192.168.10.3
案例4:expect 实现 ssh 公钥推送
#!/usr/bin/bash
>ip.txt #清空ip.txt文件
password=123.com
#测试expect是否安装
rpm -q expect &> /dev/null
if [ $? -ne 0 ];then
yum -y install expect &> /dev/null && \ echo -e "\e[1;32m expect 安装成功 \e[0m"
fi
#测试是否存在私钥
if [ ! -f ~/.ssh/id_rsa ];then
ssh-keygen -P "" -f ~/.ssh/id_rsa && \
echo -e "\e[1;32m id_rsa 创建结束 \e[0m"
fi
for i in {1..5}
do
{
ip=192.168.10.$i
ping -c1 -W1 $ip &> /dev/null
if [ $? -eq 0 ];then
echo "正在向$ip 传送公钥..." >> /tmp/ip.txt
#通过<<-EOF EOF 执行expect语言
/usr/bin/expect <<-EOF
#spawn开启一个会话
spawn ssh-copy-id $ip
expect {
"yes/no" {send "yes\r"; exp_continue}
"password:" {send "$password\r"}
}
expect eof
EOF
#EOF结束expect语言
else
echo "该主机尚未存活"
fi
}&
done
————————————————
版权声明:本文为CSDN博主「 清欢渡.」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/shm19990131/article/details/106190738