您的位置:首页 > 运维架构 > Shell

shell编程之 expect预期交互

2019-06-01 17:55 633 查看

方案
expect是基于TCL编写的自动交互式程序,可以为交互式过程(比如FTP、SSH等登录过程)自动输送预先准备的文本或指令,而无需人工干预。触发的依据是预期会出现的特征提示文本。
常见的expect指令:
定义环境变量:set 变量名 变量值
创建交互式进程:spawn 交互式命令行
触发预期交互:expect “预期会出现的文本关键词:” { send “发送的文本\r” }
在spawn建立的进程中允许交互指令:interact
步骤

实现此案例需要按照如下步骤进行。

步骤一:准备expect及SSH测试环境
1)安装expect工具

[root@svr5 ~]# yum  -y  install  expect  				//安装expect
.. ..
Installed:
expect.x86_64 0:5.44.1.15-5.el6_4
Dependency Installed:
tcl.x86_64 1:8.5.7-6.el6

[root@svr5 ~]# which expect  							//确认expect路径
/usr/bin/expect

2)准备SSH测试环境
以本机192.168.4.5为例,只要启用sshd服务,并添加mike用户即可:

[root@svr5 ~]# service sshd restart
停止 sshd:                                                [确定]
正在启动 sshd:                                            [确定]

[root@svr5 ~]# useradd mike
[root@svr5 ~]# echo 1234567 | passwd --stdin mike
更改用户 mike 的密码 。
passwd: 所有的身份验证令牌已经成功更新。

步骤二:编写expect_ssh脚本,实现免交互登录
1)任务需求及思路分析
在SSH登录过程中,如果是第一次连接到该目标主机,则首先会被要求接受密钥,然后才提示输入密码:

[root@svr5 ~]# ssh mike@192.168.4.5  							//连接目标主机
The authenticity of host '192.168.4.5 (192.168.4.5)' can't be established.
RSA key fingerprint is 58:a0:d6:00:c7:f1:34:5d:6c:6d:70:ce:e0:20:f8:f3.
Are you sure you want to continue connecting (yes/no)? yes  		//接受密钥
Warning: Permanently added '192.168.4.5' (RSA) to the list of known hosts.
mike@192.168.4.5's password:   								//验证密码
Last login: Thu May  7 22:05:44 2015 from 192.168.4.5
[mike@svr5 ~]$ exit 											//返回客户端
logout
Connection to 192.168.4.5 closed.

在上述过程中,第一次交互发生在出现“… …(yes/no)?”的提示时,需要提供“yes”;而第二次交互发生在出现“… …password:”提示时,需要提供登录用户的密码;交互登录成功以后,需要在“[mike@svr5 ~]$”环境执行exit命令来断开连接。
当然,如果SSH登录并不是第一次,则接受密钥的环节就没有了,而是直接进入验证密码的过程:

[root@svr5 ~]# ssh mike@192.168.4.5  							//连接目标主机
mike@192.168.4.5's password:   								//验证密码
Last login: Mon May 11 12:02:39 2015 from 192.168.4.5
[mike@svr5 ~]$ exit 											//返回客户端
logout
Connection to 192.168.4.5 closed.

综上所述,应该预先知道SSH连接目标主机的正常交互过程。需要在脚本中来实现这些交互过程时,就可以利用expect工具,通过spawn指令来创建ssh登录进程,并设置expect指令来识别预期会出现的提示文本、提供相应的文本,甚至进一步发送相应的子进程交互指令。其中用户名、IP地址可以提前用set设好变量,这样更加方便。
2)根据实现思路编写脚本文件
脚本内容参考如下:

[root@svr5 ~]# vim  expect_ssh.sh
#!/usr/bin/expect
set host 192.168.4.5  							#//定义变量
set user mike
set password "1234567"
spawn ssh $user@$host  						#//创建交互式进程
expect "password:" { send "$password\r" }  		#//自动发送密码
expect "\[$user\@" { send "pwd > /tmp/$user.txt ; exit\r" }
#//发送交互式命令
interact  									#//允许交互式环境

[root@svr5 ~]# chmod  +x  expect_ssh.sh

3)验证、测试脚本
执行脚本前,目标主机上并没有/tmp/mike.txt文件:

[root@svr5 ~]# ls /tmp/mike.txt
ls: 无法访问/tmp/mike.txt: 没有那个文件或目录

执行expect_ssh.sh自动登录脚本:

[root@svr5 ~]# expect_ssh.sh
spawn ssh mike@192.168.4.5
mike@192.168.4.5's password:
Last login: Mon May 11 12:08:47 2015 from 192.168.4.5
pwd > /tmp/mike.txt ; exit
[mike@svr5 ~]$ pwd > /tmp/mike.txt ; exit
logout
Connection to 192.168.4.5 closed.

再次检查目标主机,会看到已经建立了/tmp/mike.txt文件,说明expect自动登录并远程执行命令成功:

[root@svr5 ~]# ls -l /tmp/mike.txt
-rw-rw-r--. 1 mike mike 11 5月  11 12:17 /tmp/mike.txt
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: