python Pexpect模块的使用


Posted in Python onDecember 25, 2020

Pexpect简介

在讲解Pexpect之前,我们需要先了解一下Expect这个脚本语言,它是由TCL语言实现的,主要用于人机交互式对话的自动化控制,可以用来完成ssh、ftp、telnet等命令行程序的自动化交互。Pexpect其实就是一个用Python语言实现的类Expect功能的模块,通过它就可以在Python中完成Expect所完成的功能。

Pexpect的基本工作流程,基本可以分为以下三个步骤:

  1. 首先用spawn来执行一个程序;
  2. 然后用expect方法来等待指定的关键字,这个关键字是被执行的程序打印到标准输出上面的;
  3. 最后当发现这个关键字以后,使用send/sendline方法发送字符串给这个程序。

通常在程序中第一步只需要做一次,第二步和第三步会不停的循环来完成整个工作。当然在Pexpect中还有很多其他方法,编写程序时可以根据自己的需求选择使用。

Pexpect API

spawn类

class spawn(SpawnBase):
  '''This is the main class interface for Pexpect. Use this class to start
  and control child applications. '''

  # This is purely informational now - changing it has no effect
  use_native_pty_fork = use_native_pty_fork
  
	def __init__(self, command, args=[], timeout=30, maxread=2000,
           searchwindowsize=None, logfile=None, cwd=None, env=None,
           ignore_sighup=False, echo=True, preexec_fn=None,
           encoding=None, codec_errors='strict', dimensions=None,
           use_poll=False):

通过spawn()方法用来执行一个程序,返回程序的操作句柄,后续就可以通过操作句柄来与这个程序进行交互了。

# 子程序退出时会引发pexpect.EOF异常,即如果捕捉到pexpect.EOF则说明子程序已退出
process = pexpect.spawn('ls -l')
process.expect(pexpect.EOF)
result = process.before.decode()
print(result)

command参数并不支持字符的特殊含义(比如管道符、通配符、重定向符等),在Linux系统中如果想使用这些符号的特殊含义就必须加上shell来运行。

# 示例一
process = pexpect.spawn('bash -c "ls -l | wc -l"')
process.expect(pexpect.EOF)

# 示例二
# 第一个参数为主程序,而args列表里的元素是主程序的参数
process = pexpect.spawn('bash', ['-c', 'ls -l | wc -l'])
process.expect(pexpect.EOF)

expect()方法

当使用spawn()方法启动了一个程序并返回程序控制句柄后,就可以使用expect()方法来等待指定的关键字了。关键字可以是字符串、正则表达式、EOF、TIMEOUT或者以上类型组成的列表,用来匹配子程序返回的结果。如果只提供字符串等非列表,则匹配成功后返回0,如果提供列表,则返回匹配成功的列表元素的索引,匹配失败会抛出异常。

process = pexpect.spawn('ls -l')
# 匹配expect字符
process.expect('expect')

before/after/match:当expect()匹配到关键字之后,系统会自动给这三个变量赋值,通过这三个变量可以获取子程序运行输出。

  • before:保存了到匹配到关键字为止,缓存里面已有的所有数据。也就是说如果缓存里缓存了100个字符的时候匹配到了关键字,那before就是除了匹配到的关键字之外的所有字符。
  • after:保存了匹配到了关键字。
  • match:保存的是匹配到的正则表达式的实例,和上面的after相比一个是匹配到的字符串,一个是匹配到的正则表达式实例。
process = pexpect.spawn('ls -l')
process.expect('expect')
print(process.before.decode())
print(process.after.decode())
print(process.match)

如果expect()过程中发生错误,那么before保存到目前为止缓存里的所有数据,after和match都是None。

如果没匹配成功则会抛出异常,可以通过匹配异常,让异常不在终端显示。

process = pexpect.spawn('ls -l')
# 返回0表示匹配成功,返回1和2表示匹配到了异常
index = process.expect(['expect', pexpect.EOF, pexpect.TIMEOUT])
print(index)

send()/sendline()方法

sendline()和send()的区别就是sendline()发送的是带回车符的字符串。

process = pexpect.spawn('nslookup')
process.expect('>')
process.sendline('www.baidu.com')
process.expect('>')
print(process.before.decode())
process.sendline('exit')

Pexpect还提供了很多其他方法,这里不再详细阐述,使用时可参考其官方文档。

interact()方法

interact()表示将终端控制权交给用户(或者说将标准输入交给用户)。通常情况下Pexpect会接管所有的输入和输出,如果需要用户介入完成部分工作的时候,interact()就派上用场了。

# 让出控制权给用户
process.interact()
# 通过设置escape_character的值定义返回码,当用户输入此值后,会将控制权重新交给pexpect
process.interact(escape_character='\x1d', input_filter=None, output_filter=None)

应用示例

接下来通过SSH连接远程服务器的示例来体验下Pexpect的使用方法。

#!/usr/bin/env python3.6
#-*- coding:utf-8 -*-

import pexpect

def main(server):
  command = 'ssh -p %s %s@%s' % (server['port'], server['username'], server['hostname'])
  process = pexpect.spawn(command, timeout=30)
  print(f'命令: {command}')
  expect_list = [
    'yes/no',
    'password:',
    pexpect.EOF,
    pexpect.TIMEOUT,
  ]
  index = process.expect(expect_list)
  print(f'匹配到: {index} => {expect_list[index]}')
  if index == 0: 
    process.sendline("yes")
    expect_list = [
      'password:',
      pexpect.EOF,
      pexpect.TIMEOUT,
    ]
    index = process.expect(expect_list)
    print(f'匹配到: {index} => {expect_list[index]}')
    if index == 0:
      process.sendline(server['password'])
      process.interact()
    else:
      print('EOF or TIMEOUT')
  elif index == 1:
    process.sendline(server['password'])
    process.interact()
  else:
    print('EOF or TIMEOUT')
  
if __name__ == '__main__':
  server = {
    'hostname': '192.168.1.100',
    'port': '22',
    'username': 'admin',
    'password': 'ABuklhsfnVyxI',
  }
  main(server)

以上就是python Pexpect模块的使用的详细内容,更多关于python Pexpect模块的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python进阶教程之异常处理
Aug 30 Python
Python __setattr__、 __getattr__、 __delattr__、__call__用法示例
Mar 06 Python
Python实现二叉堆
Feb 03 Python
利用 Monkey 命令操作屏幕快速滑动
Dec 07 Python
详解python之配置日志的几种方式
May 22 Python
Python基于dom操作xml数据的方法示例
May 12 Python
Python tkinter label 更新方法
Oct 11 Python
Python实现基于SVM的分类器的方法
Jul 19 Python
检测tensorflow是否使用gpu进行计算的方式
Feb 03 Python
Python sorted排序方法如何实现
Mar 31 Python
django中url映射规则和服务端响应顺序的实现
Apr 02 Python
python3实现简单飞机大战
Nov 29 Python
Python中读取文件名中的数字的实例详解
Dec 25 #Python
Python的logging模块基本用法
Dec 24 #Python
python 通过exifread读取照片信息
Dec 24 #Python
python 如何上传包到pypi
Dec 24 #Python
python 基于PYMYSQL使用MYSQL数据库
Dec 24 #Python
python xlsxwriter模块的使用
Dec 24 #Python
想学画画?python满足你!
Dec 24 #Python
You might like
PHP 存储文本换行实现方法
2010/01/05 PHP
php检测url是否存在的方法
2015/04/14 PHP
php 策略模式原理与应用深入理解
2019/09/25 PHP
Laravel框架中集成MongoDB和使用详解
2019/10/17 PHP
laravel框架中表单请求类型和CSRF防护实例分析
2019/11/23 PHP
javascript数组的扩展实现代码集合
2008/06/01 Javascript
Javascript在IE下设置innerHTML时出现未知的运行时错误的解决方法
2011/01/12 Javascript
基于jQuery替换table中的内容并显示进度条的代码
2011/08/02 Javascript
40款非常有用的 jQuery 插件推荐(系列一)
2011/12/21 Javascript
NodeJs中的非阻塞方法介绍
2012/06/05 NodeJs
jquery 获取标签名(tagName)示例代码
2013/07/11 Javascript
javascript unicode与GBK2312(中文)编码转换方法
2013/11/14 Javascript
ie8本地图片上传预览示例代码
2014/01/12 Javascript
同一个网页中实现多个JavaScript特效的方法
2015/02/02 Javascript
nodejs中向HTTP响应传送进程的输出
2017/03/19 NodeJs
Vue组件开发之LeanCloud带图形校验码的短信发送功能
2017/11/07 Javascript
使用vue实现grid-layout功能实例代码
2018/01/05 Javascript
vue cli 3.0 搭建项目的图文教程
2019/05/17 Javascript
python 图片验证码代码分享
2012/07/04 Python
Python中利用函数装饰器实现备忘功能
2015/03/30 Python
python中threading超线程用法实例分析
2015/05/16 Python
简单介绍Python的Django框架加载模版的方式
2015/07/20 Python
Python中遍历字典过程中更改元素导致异常的解决方法
2016/05/12 Python
python引入不同文件夹下的自定义模块方法
2018/10/27 Python
Python面向对象程序设计多继承和多态用法示例
2019/04/08 Python
python selenium 执行完毕关闭chromedriver进程示例
2019/11/15 Python
Ubuntu16.04安装python3.6.5步骤详解
2020/01/10 Python
python中用ggplot绘制画图实例讲解
2021/01/26 Python
python工具快速为音视频自动生成字幕(使用说明)
2021/01/27 Python
HTML5 form标签之解放表单验证、增加文件上传、集成拖放的使用方法
2013/04/24 HTML / CSS
芬兰攀岩、山地运动和户外活动用品购物网站:Bergfreunde
2016/10/06 全球购物
加拿大最大的箱包及旅游配件零售商:Bentley Leathers
2017/07/19 全球购物
新西兰床上用品和家居用品购物网站:Adairs
2018/04/27 全球购物
技术总监的工作职责
2013/11/13 职场文书
村官工作鉴定评语
2014/01/27 职场文书
开服装店计划书
2014/08/15 职场文书