shell中expect解决交互问题

【Linux Shell脚本编程】expect解决脚本交互 + Shell的多进程处理
发布:TangLu2018-7-13 10:53分类: Shell 标签: bash shell

如果在没有使用密钥认证的情况下,想通过SSH来传输文件给多个主机会面临交互的问题,这在脚本中是非常不友好的。要解决这个问题的话可以使用expect这个工具,它的功能就是提前把交互中需要的内容先写好,然后在脚本执行的时候自动输入。通常用这个工具解决秘钥分发的问题,之后有了秘钥就不需要再使用它了。

1、使用yum安装expect

1
yum -y expect

2、编写一个使用expect解决ssh交互问题的案例

01
vi expect.sh
02
#!/bin/expect
03
spawn ssh root@192.168.1.100 #让expect处理该会话,也就是说执行该命令后遇到的交互内容将由expect继续
04
#下面是提前输入了可能会遇到的交互的内容以及应答方式
05
expect {
06
“yes/no” { send “yes\r”; exp_continue } #遇到引号内的关键词就发送yes指令,
07
代表回车,后面的exp_continue表示没有遇到的话继续往下执行
08
“password” { send “centos\r” };
09
}
10
interact #让会话保留在对方那边。因为是ssh连接,所以要保持连接就要将会话停住而不能退出

如果不需要保持交互的话可以写成这样的格式:

01
#!/bin/expect
02
spawn ssh root@192.168.1.100
03
expect {
04
“yes/no” { send “yes\r”; exp_continue }
05
“password” { send “centos\r” };
06
}
07
expect “#” #这里的#其实就是登陆ssh后出现的那个提示符
08
send “useradd user1\r”
09
send “echo 123456 | password --stdin user1\r”
10
expect eof #结束expect

3、还可以在expect中使用变量,格式如下

01
#!/bin/expect
02
set ip 192.168.1.100
03
set user root
04

05
spawn ssh u s e r @ user@ user@ip #让expect处理该会话,引用了变量
06

07
expect {
08
“yes/no” { send “yes\r”; exp_continue }
09
“password” { send “centos\r” };
10
}

4、还可以使用位置变量进行传参,括号内是固定格式,不用做变动,0代表第一个参数,以此类推,

01
#!/bin/expect
02
set ip [lindex $argv 0]
03
set user [lindex $argv 1]
04

05
spawn ssh u s e r @ user@ user@ip #让expect处理该会话,引用了变量
06

07
expect {
08
“yes/no” { send “yes\r”; exp_continue }
09
“password” { send “centos\r” };
10
}

5、最后使用expect执行脚本

1
expect expect.sh

示例:使用expect批量推送公钥

可以看到该脚本在for循环中用到了{}&这样的组合,这是使用多进程的方式在执行循环,然后使用wait等所有线程都执行完毕后进行最后的finish。使用多进程执行脚本时需要注意的是要结合命名管道(使用mkfifo命令创建命名管道)来控制进程的数量,否则执行大批量操作时会出错

查看源码打印?
01
#!/usr/bin/bash
02

ip.txt
03
password=yourpassword
04

05
rpm -q expect &>/dev/null
06
if [ $? -ne 0 ];then
07
yum -y install expect
08
fi
09

10
if [ ! -f ~/.ssh/id_rsa ];then
11
ssh-keygen -P “” -f ~/.ssh/id_rsa
12
fi
13

14
for i in {1…254}
15
do
16
{
17
ip=192.168.122.$i
18
ping -c1 -W1 $ip &>/dev/null
19
if [ ? − e q 0 ] ; t h e n 20 e c h o " ? -eq 0 ];then 20 echo " ?eq0];then20echo"ip" >> ip.txt
21
/usr/bin/expect <<-EOF
22
set timeout 10
23
spawn ssh-copy-id KaTeX parse error: Can't use function '\r' in math mode at position 59: …no" { send "yes\̲r̲"; exp_continue…password\r" }
27
}
28
expect eof
29
EOF
30
fi
31
}&
32
done
33
wait
34
echo “finish…”

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
expect是一个用于自动化交互的工具,可以在shell脚本使用。 expect的基本用法是: 1. 安装expect 在Ubuntu,可以使用以下命令安装expect: ``` sudo apt-get install expect ``` 2. 编写expect脚本 expect脚本的基本结构是: ``` #!/usr/bin/expect spawn [command] expect { [pattern1] {action1} [pattern2] {action2} ... } ``` 其,spawn命令用于启动被自动化的程序,pattern用于匹配程序输出的信息,action用于执行相应的操作。 例如,以下脚本可以自动登录ssh服务器: ``` #!/usr/bin/expect set timeout 10 set ip [lindex $argv 0] set username [lindex $argv 1] set password [lindex $argv 2] spawn ssh $username@$ip expect { "(yes/no)? " { send "yes\r" exp_continue } "password: " { send "$password\r" } } interact ``` 在这个脚本,首先定义了一些变量,然后使用spawn命令启动ssh连接。接着,使用expect匹配了两种不同的输出信息,一种是确认是否连接到新的主机,另一种是输入密码。当匹配到"(yes/no)?"时,发送"yes\r",并继续等待其他匹配;当匹配到"password:"时,发送密码。最后使用interact命令进入交互模式,允许用户手动操作连接。 3. 运行expect脚本 使用以下命令运行expect脚本: ``` expect [script] ``` 其,[script]是expect脚本的文件名。在运行脚本时,可以传入一些参数,例如: ``` expect ssh_login.expect 192.168.1.100 root password ``` 这将连接到IP地址为192.168.1.100的服务器,使用root用户名和password密码进行登录。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值