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 [email protected] #让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 [email protected]
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…”

你可能感兴趣的:(linux)