目录

级别一

级别二

级别三

尽量减少交互难度


级别一

固定的一个或者几个prompt。对策:定义prompt,执行命令后等待prompt的出现。可以使用正则表达式来匹配prompt。比如用于匹配linux prompt的正则表达式可以是#|\\$或者(@.*#)|(@.*\\$)。

级别二

以固定的方式进行交互。比如执行命令后,出现“password:”时,输入密码,出现“y/n”时,输入y表示同意继续。

对策:1、按顺序wait指定的内容,可以是正则匹配,然后输入相应内容。2、扩展描述prompt的正则表达式,包含所有可能出现的标志性提示,按顺序输入相应内容。

例如:

测试需求:

SSL VPN tunnel测试时,需要在互联网终端上运行SSL VPN的客户端工具来建立隧道,然后在这个互联网终端上ping ssl vpn站点内部的vm。

交互需求:

SSH登录互联网终端,sudo su之后运行SSL VPN的客户端,sudo su之后,出现password for user:时要输入密码。

运行SSL VPN的客户端后,当输出中出现“Password for VPN:”时要,输入vpn密码,当输出中出现“(Y/N)”时,输入“y”,当输出中出现“STATUS::Tunnel running”,说明隧道建立完成,可以进行后续操作了。因为这个程序在前台一直运行着,所以不会出现prompt。

解决办法(使用robot示意代码):

这里提前封装了关键字Send Command,用于在ssh连接上执行一条命令,参数regexp指明该关键字中read until regexp中等待的模式。

方式一:wait指定的内容

set_client_configuration       prompt=REGEXP:#|\\$

Send Command     sudo su    regexp=password\\sfor\\suser:

Send Command     ${internet_client_password}​​

Send Command     /home/sslvpnclient --server ${​​f1}​​[floating_ip_address]:${​​service_port}​​ --vpnuser ${​​sslvpn_username} --keepalive ​​    regexp=Password\\sfor\\sVPN:

Send Command     ${​​sslvpn_password}​​     regexp=\\(Y/N\\)

Send Command     y      regexp=STATUS::Tunnel\\srunning

方式二:扩展描述prompt的正则表达式

set_client_configuration       prompt=REGEXP:#|\\$|(Password\\sfor\\sVPN:)|\\(Y/N\\)|(STATUS::Tunnel\\srunning)|(password\\sfor\\suser:

Send Command     sudo su

Send Command     ${internet_client_password}​​

Send Command

...    /home/sslvpnclient --server ${​​f1}​​[floating_ip_address]:${​​service_port}​​​​​​​​​ --vpnuser ${​​​​​​​​​sslvpn_username} --keepalive

​​Send Command     ${​​​​​​​​​sslvpn_password}​​​​​​​​​

Send Command     y

级别三

不确定下一步将会要求输入什么,比如,可能要求输入密码,也可能要求输入y进行确定。这个时候需要根据提示来决定输入的内容。

例如ssh登录到一台设备后,在这台设备上再通过ssh命令登录另一台设备,客户端没有key或者服务端的key更新后,登陆时会提示“yes/no?”,否者只会提示输入密码“password:”。

TCL的expect包非常擅长处理这种场景,支持匹配列表和内置循环匹配功能。

现在来说一下python的解决方案。

Python有pexpect包,它支持用于匹配的列表,但是没有内置的循环匹配功能,所以需要自己写循环。

可以不使用pexpect,我们只需要将可能的提示都扩展到描述prompt的正则表达式中。循环中写几个if分支,通过当前的特征性提示内容,决定下一步操作。代码如下:

这里提前封装了一个函数send_command,用于在ssh连接上执行一条命令。s: SSHLibrary instance。log是logging.getLogger()返回的logger。在这里,这两个参数不是重点,大家可以忽略它们。

def ssh_connect (s, log, host, port, username, password):#扩展prompt的正则表达式s.set_client_configuration(prompt="REGEXP:#|\\$|password:|\\(yes/no.*\\?")output = send_command(s,log,f'ssh -p {port} {username}@{host}')while True:if 'password:' in output:output = send_command(s,log,password)breakelif 'yes/no' in output:output = send_command(s,log,'yes')#恢复prompt的正则表达式s.set_client_configuration(prompt="REGEXP:#|\\$")

接下来我把这个功能抽象成一个函数,以达到通用的级别三交互的效果。

函数参数说明:

command是要执行的主命令。

expects是两层列表。对于每一个内层列表,第一个元素是期望匹配到的正则表达式式,第二个元素是匹配到这个正则表达式后要输入的内容,第三个元素表示退出循环还是继续循环。

def expect(s, log, command, expects):#为了方便阅读代码,为exp中每个index取个名字。reg, cmd, control = 0, 1, 2#扩展prompt的正则表达式prompt = s.get_connection().prompt#exp[reg]外面加圆括号是为了避免exp[reg]中本身就有|导致的结合性问题for exp in expects:prompt += "|" + "(" + exp[reg] + ")"s.set_client_configuration(prompt=prompt)output = send_command(s,log,command)break_flag=Falsewhile True:for exp in expects:if re.search(exp[reg], output):output = send_command(s, log, exp[cmd])if exp[control]=="break":break_flag=Truebreakif break_flag:break#恢复prompt的正则表达式s.set_client_configuration(prompt="REGEXP:#|\\$")

使用示意:

s = SSHLibrary()
s.open_connection("10.66.196.39",prompt=linux_prompt)
s.login("root","Ionqa123!@#")
log = Logger(logger="expr",filename="expr").getlog()
command = f'ssh root@10.66.196.30'
expects = [["password:", "password", "break"],["\\(yes/no.*\\?", "yes", "continue"],
]
expect(s,log,command,expects)
s.close_connection()

是不是有点tcl expect的味道,我把对匹配列表的支持和循环匹配的能力都封装在了上面的expect()函数中。

尽量减少交互难度

为了避免麻烦,应该尽量减少困难交互场景的出现。如果执行命令时加上某个参数就可以不用额外交互,那就带上这个参数。比如执行命令时同时就输入密码,执行命令时要求不进行某种确认。比如ssh命令使用选项-o StrictHostKeyChecking=no就可以避免出现提示“continue connecting (yes/no/[fingerprint])?”。比如ssh登录时如果没有条件输入密码,则可以配置使用免密登录方式。

命令行交互性三个级别及其自动化解决方案相关推荐

  1. Electron-vue开发实战7——命令行调用与系统级别右键菜单项的实现

    原文首发在我的博客,欢迎关注! 前言 前段时间,我用electron-vue开发了一款跨平台(目前支持主流三大桌面操作系统)的免费开源的图床上传应用--PicGo,在开发过程中踩了不少的坑,不仅来自应 ...

  2. 快速打开文件命令行的三种方法

    快速打开文件命令行的三种方法 方法一:Window + R  一般专业电脑工作者最常用的就是Window + R呼出运行窗口然后点击cmd进入命令行 然后直接输入 cd + 文件夹路径 最后敲个回车即 ...

  3. 探究 Xcode 命令行用法三:xcodebuild 打包实践(上)

    本文还是 adat 项目的延伸,开始介绍打包实践.打包相关的内容繁多,作者把它分成了多篇文章,本文主要是概念部分.理解这些概念对于自己动手编写打包命令至关重要.如果你使用 fastlane.bitri ...

  4. Windows 启动命令行的三种方式

    Windows 启动命令行的三种方式 文章目录 Windows 启动命令行的三种方式 1. 一般启动 2. 右键菜单 3. 推荐启动 1. 一般启动 Win + R 输入 cmd 后回车 此种方式启动 ...

  5. 关于虚拟机纯命令行centos解决web上网认证的解决方案

    关于虚拟机纯命令行centos解决web上网认证的解决方案 虚拟机版本:CentOS Linux release 7.1.1503 (Core) 在我们学校,有校园网的存在,导致我在配置虚拟机的时候遇 ...

  6. oracle SQL 命令行(三.增删改查)

    SQL> select * from stu;SON SNAME SAGE -------- -------------------- ---------- 1001 张三 18 1003 李四 ...

  7. 使用 dotnet 命令行配合 vscode 完成一个完整 .NET 解决方案的编写和调试

    如果你是开发个人项目,那就直接用 Visual Studio Community 版本吧,对个人免费,对小团体免费,不需要这么折腾. 如果你是 Mac / Linux 用户,不想用 Visual St ...

  8. 《Linux命令行与shell脚本编程大全》(第三版)读书笔记

    第一部分 Linux命令行 第三章.基本的bash shell命令 bash手册 man 命令 例子: man cat 空格翻页.回车下一行.左右键看右侧(左侧)内容.q退出 info info in ...

  9. 软工+C(11): 从命令行开始逐步培养编程能力(Java)

    上一篇:助教指南,持续更新... // Version: 0.0.4 许多人,所不知道的是,每一种编程语言都有其对应的单元测试框架,对程序在不同阶段的测试环节也概念模糊.在实际动手编写程序许久之后才听 ...

最新文章

  1. 阿里云云服务器硬盘分区及挂载
  2. linux系统虚拟化测试,网络性能与磁盘测试 - Linux虚拟化性能PK:Ubuntu系统6大版本_Linux新闻_Linux公社-Linux系统门户网站...
  3. SharePoint 2010 工作流解决方案:将 SharePoint Designer 可重用工作流导入 Visual Studio...
  4. NAACL’21 | 来看如何让模型学会因为所以但是如果
  5. 探索App保活黑科技
  6. LinuxC高级day1
  7. C#之Chart控件使用
  8. woc,又一个大佬辞职了……
  9. 平板电脑触摸屏行业研究及十四五规划分析报告
  10. pn532检测不到nfc设备_华为、小米又增回NFC功能,苹果却一直无NFC功能,NFC能否成为关键?...
  11. 【译文】利用STAN做贝叶斯回归分析:Part 1 正态回归
  12. 电机专题1:电机原理
  13. 网红模块ESP8266与墨水屏e-Paper 的结合,实现网络刷新内容。
  14. Xcode 更改默认版本 xcode-select
  15. 激光雷达进入前装上车“蜜月期”,部分厂商备战2024年“决战”
  16. 制作PPT学习笔记(1)
  17. html5公开课宣传文案,《自信演讲》公开课文案
  18. html 自动返回首页,mui页面跳转,进入子页面后自动回到首页
  19. 金沙数据-《大话搜索引擎》之开篇
  20. 二代身份证编码规则及校验代码实现

热门文章

  1. RTP有效负载(载荷)类型 (RTP Payload Type)
  2. 通过查询教室课表,选择最佳的空教室自习(少换教室) Python 附源码
  3. 【Verilog】一、Verilog的always使用
  4. 阿里CEO张勇:数字经济已开启新的未来
  5. C++ Primer Plus学习笔记之类和动态内存分配
  6. 中文OCR场景文字检测工具cnstd、文本框文字识别工具cnocr调试评测
  7. 国家促进普通高校毕业生就业的政策
  8. 测试驱动的嵌入式C语言开发(TDD)(第1-3章)
  9. html audio重新播放,javascript – Web Audio API:如何重新开始播放声音?
  10. 引用账户锁定无法登录_锁定电脑后重登录,出现“引用账户当前已锁定,且可能无法登录”提示。是怎么回事?...