简单介绍
pexpect是 Don Libes 的 Expect 语言的一个 Python 实现,是一个用来启动子程序,并使用正则表达式对程序输出做出特定响应,以此实现与其自动交互的 Python 模块。它可以用来实现与ssh, ftp, telnet等程序的自动交互,参考官方文档:https://pexpect.readthedocs.io/en/stable/

安装均可以使用pip进行

注意:windows和linux安装模块是不同的。如下:
在linux下安装:pip3 install pexpect
在windows下安装: pip3.exe install winpexpect

在windows系统里创建子程序是:
import winpexpect
child = winpexpect.winspawn('command')
另:run(), pxssh()均不可使用

在linux系统里创建子程序是:
import pexpect
child = pexpect.spawn('cmd')

模块内主要的类/函数介绍

spawn / winspawn 类
作用:可以实现更复杂的交互,通过生成子程序进行sendline(发送命令)与expect(返回操作符)进行交互。
class spawn
def __init__(self, command, args=[], timeout=30, maxread=2000,
searchwindowsize=None, logfile=None, cwd=None, env=None,
username=None, domain=None, password=None)

个别参数解释:
timeout:交互等待的超时值,默认30秒
maxread:设置read buffer大小,
searchwindowsize:从输入缓冲区中进行模式匹配的位置,默认从开始匹配。
logfile:指定日志的记录位置

注意:pexpect不支持管道,重定向或通配符,如果需要使用,需要重新打开一个shell
简单用法:
# 第一步创建子程序,输入执行的操作命令,我这里是以telnet远程终端为例
child = pexpect.spawn('telnet ipaddress')
# 第二步从子命令返回的结果中进行匹配,语法:expect(pattern, timeout=-1),

pattern参数说明:可以为字符串,正则表达式,EOF,TIMEOUT,或者是以上类型的列表,若只提供字符串,匹配成功后返回0,若提供列表,匹配成功后返回列表的索引序号。未匹配成功,则会引发异常

timeout:为-1 使用默认的超时期限,设置为NONE,将阻塞至返回信息
child.expect('password:')
# 第三步匹配成功后,发送交互信息,这里发送密码
child.sendline(mypassword)

获取命令执行结果主要由3个基本属性。

child.before:输出匹配点之前的命令执行结果

child.after:输出匹配成功后的匹配点内容,如标识符:hostname#>

child.match:保存已匹配的匹配点对象,可以使用string,打印命令的执行结果。

pxssh类
是pexpect的派生类,用于建立ssh连接,比pexpect直接使用ssh时简单一些,内建3个方法:
login() 建立到目标机器的ssh连接;
logout() 释放该连接;
prompt() 等待提示符,通常用于等待命令执行结束。

pexpect.EOF 异常错误
获取pexpect错误信息,可能会有两种 EOF 异常被抛出,但是他们除了显示的信息不同,其实本质上是相同的。为了实用的目的,不需要区分它们,他们只是给了些关于你的 python 程序到底运行在哪个平台上的额外信息,这两个显示信息是:
End Of File (EOF) in read(). Exception style platform.
End Of File (EOF) in read(). Empty string style platform.
有些 UNIX 平台,当你读取一个处于 EOF 状态的文件描述符时,会抛出异常,其他 UNIX 平台,却只会静静地返回一个空字符串来表明该文件已经达到了状态。

pexpect.TIMEOUT异常错误
如果子程序没有在指定的时间内生成任何 output,那么 expect() 和 read() 都会产生 TIMEOUT 异常。超时默认是 30s,可以在 expect() 和 spawn 构造函数初始化时指定为其它时间
child.expect('password:', timeout=120) # 等待 120s
如果你想让 expect() 和 read() 忽略超时限制,即无限期阻塞住直到有 output 产生,设置 timeout 参数为 None。
代码如:
child = pexpect.spawn( "telnet 域名" )
child.expect( "login", timeout=None )

以上两个错误可以使用try语句来处理报错
try:
child=pexpect.spawn('telnet ip',timeout=5)
child.logfile = log
child.logfile_send=sys.stdout
child.expect("New password:")
child.sendline(mypassword)
child.expect("Retype new password:")
child.sendline(mypassword)
child.expect("passwd: all authentication tokens updated successfully.")
except pexpect.EOF:
pass
except pexpect.TIMEOUT:
pass

实例:自动登陆ftp

 import pexpect
# 即将 ftp 所要登录的远程主机的域名
ipAddress = '域名名称'
# 登录用户名
loginName = 'username'
# 用户名密码
loginPassword = 'password'
# 拼凑 ftp 将要执行的命令
cmd = 'ftp ' + ipAddress
# 利用 cmd 命令作为 spawn 类构造函数的参数,生成一个 spawn 类的对象
child = pexpect.spawn(cmd)
# 期望具有提示输入用户名的字符出现
index = child.expect(["(?i)name", "(?i)Unknown host", pexpect.EOF, pexpect.TIMEOUT])
# 匹配到了列表索引为0的字符串 "(?i)name",表明接下来要输入用户名
if index == 0:
# 发送登录用户名 + 换行符给子程序.
child.sendline(loginName)
# 期望 "(?i)password" 具有提示输入密码的字符出现.
index = child.expect(["(?i)password", pexpect.EOF, pexpect.TIMEOUT])
# 匹配到了 pexpect.EOF 或 pexpect.TIMEOUT,表示超时或者 EOF,程序打印提示信息并退出.
if (index != 0):
print "ftp login failed"
child.close(force=True)
# 匹配到了密码提示符,发送密码 + 换行符给子程序.
child.sendline(loginPassword)
# 期望登录成功后,提示符 "ftp>" 字符出现.
index = child.expect( ['ftp>', 'Login incorrect', 'Service not available',
pexpect.EOF, pexpect.TIMEOUT])
# 匹配到了 'ftp>',登录成功.
if (index == 0):
print 'Congratulations! ftp login correct!'
# 发送 'bin'+ 换行符给子程序,表示接下来使用二进制模式来传输文件.
child.sendline("bin")
print 'getting a file...'
# 向子程序发送下载文件 rmall 的命令.
child.sendline("get rmall")
# 期望下载成功后,出现 'Transfer complete.*ftp>',其实下载成功后,
# 会出现以下类似于以下的提示信息:
# 200 PORT command successful.
# 150 Opening data connection for rmall (548 bytes).
# 226 Transfer complete.
# 548 bytes received in 0.00019 seconds (2.8e+03 Kbytes/s)
# 所以直接用正则表达式 '.*' 将 'Transfer complete' 和提示符 'ftp>' 之间的字符全省去.
index = child.expect( ['Transfer complete.*ftp>', pexpect.EOF, pexpect.TIMEOUT] )
# 匹配到了 pexpect.EOF 或 pexpect.TIMEOUT,表示超时或者 EOF,程序打印提示信息并退出.
if (index != 0):
print "failed to get the file"
child.close(force=True)
# 匹配到了 'Transfer complete.*ftp>',表明下载文件成功,打印成功信息,并输入 'bye',结束 ftp session.
print 'successfully received the file'
child.sendline("bye")
# 用户名或密码不对,会先出现 'Login incorrect',然后仍会出现 'ftp>',但是 pexpect 是最小匹配,不是贪婪匹配,
# 所以如果用户名或密码不对,会匹配到 'Login incorrect',而不是 'ftp>',然后程序打印提示信息并退出.
elif (index == 1):
print "You entered an invalid login name or password. Program quits!"
child.close(force=True)
# 匹配到了 'Service not available',一般表明 421 Service not available, remote server has closed connection,程序打印提示信息并退出.
# 匹配到了 pexpect.EOF 或 pexpect.TIMEOUT,表示超时或者 EOF,程序打印提示信息并退出.
else:
print "ftp login failed! index = " + index
child.close(force=True)

实例:自动登陆交换机执行一条命令后退出,最好在linux系统下进行测试,在windows下使用winpexpect不好用

 #!/opt/python3/bin/python3
# _*_ coding:utf-8 _*_
# Author: Yong import pexpect
# 基本信息
ipAddr = '交换机IP'
pwd = '交换机登陆密码'
cmd = 'telnet ' + ipAddr # 连接设备,创建子进程
child = pexpect.spawn(cmd, timeout=300)
# 进行匹配返回标识符
index = child.expect(['Password:', pexpect.EOF, pexpect.TIMEOUT])
# 匹配到列表索引0的内容
if index == 0:
# 网络设备登陆直接提示密码,发送密码
child.sendline(pwd)
# 匹配返回标识符
index = child.expect('<A-3F-30>')
# 未匹配到标识符,退出
if index != 0:
exit('密码错误')
print('密码验证完成')
# 发送执行的命令
child.sendline('display version')
# 匹配返回的标识符
child.expect('<A-3F-30>')
# 打印命令执行结果
print(child.before)
# print('将telnet子程序执行权交给用户')
# child.interact() else:
# 匹配到EOF 或者TIMEOUT表示超过时间限制
print('telnet faild, EOF OR TIMEOUT',pexpect.EOF)
# 关闭连接
child.close()

python 终端模拟模块 pexpect的更多相关文章

  1. Python模块之pexpect

    一.pexpect模块介绍 Pexpect使Python成为控制其他应用程序的更好工具.可以理解为Linux下的expect的Python封装,通过pexpect我们可以实现对ssh,ftp,pass ...

  2. Python中的Pexpect模块的简单使用

    Pexpect 是一个用来启动子程序并对其进行自动控制的 Python 模块. Pexpect 可以用来和像 ssh.ftp.passwd.telnet 等命令行程序进行自动交互.以下所有代码都是在K ...

  3. python终端颜色设置

    1.颜色定义说明 格式:\033[显示方式;前景色;背景色m   前景色 背景色 颜色 --------------------------------------- 30 40  黑色 31 41 ...

  4. Python终端如何输出彩色字体

    实现过程:       终端的字符颜色是用转义序列控制的,是文本模式下的系统显示功能,和具体的语言无关.       转义序列是以ESC开头,即用\033来完成(ESC的ASCII码用十进制表示是27 ...

  5. Python SSH登陆--pexpect,pxssh

    from pexpect import pxssh host = '192.168.80.139'user = 'allen'password = 'allen'command = 'df -h' d ...

  6. python终端中退格键,方向键不能使用

    在安装Python的时候先安装 yum install readline-devel.x86_64 -y 如果python已经安装过了就重新安装 ./configure    make all mak ...

  7. Python终端输出打印彩色字体的方法

    一  实现过程 终端的字符颜色是用转义序列控制的,是文本模式下的系统显示功能,和具体的语言无关. 转义序列是以ESC开头,即用\033来完成(ESC的ASCII码用十进制表示是27,用八进制表示就是0 ...

  8. Python 终端输出字体颜色

    终端的字符颜色是用转义序列控制的,是文本模式下的系统显示功能,和具体的语言无关.             转义序列是以ESC开头,即用\033来完成(ESC的ASCII码用十进制表示是27,用八进制表 ...

  9. python终端打印带颜色的print

    原理 实现过程:       终端的字符颜色是用转义序列控制的,是文本模式下的系统显示功能,和具体的语言无关.       转义序列是以ESC开头,即用\033来完成(ESC的ASCII码用十进制表示 ...

随机推荐

  1. python3.6:DLL load failed:找不到指定的模块(from PyQt5 import QtCore)

    本人小白搭建pyqt环境时遇到问题 运行代码 from PyQt5 import QtCore' 发现错误 ImportError: DLL load failed: 找不到指定的模块 这个问题折磨了 ...

  2. Python9-事件及队列-day37

    信号量 from multiprocessing import Process from multiprocessing import Semaphore import time import ran ...

  3. 杭电 1155 Bungee Jumping(物理题)

    Problem Description Once again, James Bond is fleeing from some evil people who want to see him dead ...

  4. Leetcode 81. 搜索旋转排序数组 II

    题目链接 https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/description/ 题目描述 假设按照升序排序的数 ...

  5. VSCode编译C/C++(一)MinGW安装配置指南

    为什么不用IDE? 更加专业.轻便.其过程对于理解计算机也有更多的帮助 安装过程: 首先进入http://mingw.org/  ,点击右侧最新发布,可以下载,然后安装 点击桌面MinGWInstal ...

  6. 枚举进程——暴力搜索内存(Ring0)

    上面说过了隐藏进程,这篇博客我们就简单描述一下暴力搜索进程. 一个进程要运行,必然会加载到内存中,断链隐藏进程只是把EPROCESS从链表上摘除了,但它还是驻留在内存中的.这样我们就有了找到它的方法. ...

  7. matlab图形handle

  8. 回调深入理解 同步回调 以android中View.OnClickListener为列

    现在来分析分析下Android View的点击方法onclick();我们知道onclick()是一个回调方法,当用户点击View就执行这个方法,我们用Button来举例好了   //这个是View的 ...

  9. 光学字符识别OCR-2

    灰度聚类 接着我们就对图像的色彩进行聚类.聚类的有两个事实依据:         1.灰度分辨率   肉眼的灰度分辨率大概为40,因此对于像素值254和255,在我们肉眼看来都 只是白色:       ...

  10. 不可取代的网站开发工具---------dreamweaver

    现在web开发的工具越来越多,sublime text,webstorm等web开发工具日益崛起,一直威胁着当年网页三剑客之一的dreamweaver工具的地位,然而dreamweaver却是无法取代 ...