Python模块之pexpect详解
Python模块之pexpect详解(一)
- 一、pexpect模块介绍
- 二、Pexpect的安装
- 三、pexpect的核心组件
- 3.1 spawn类
- 3.1.1 简介
- 3.1.2 使用流程
- 3.1.3 构造方法参数
- (1)command
- (2)args=[]
- (5)logfile=None
- (6)cwd=None
- 3.1.4 基本属性和方法
- (1)expect()连续匹配
- (2)sendline(s='')
- 3.1.5 其他发送信息的方法
- 3.1.6 其他获取结果的方法
- 3.1.7 其他常用方法
- 3.1.8 控制子程序方法
- 3.2 run函数
- 四、Pexpect封装工具
一、pexpect模块介绍
Pexpect使Python成为控制其他应用程序的更好工具。可以理解为Linux下的expect的Python封装,通过pexpect我们可以实现对ssh,ftp,passwd,telnet等命令行进行自动交互,而无需人工干涉来达到自动化的目的
二、Pexpect的安装
#python2
pip install pexpect#python3
pip3 install pexpect
三、pexpect的核心组件
3.1 spawn类
3.1.1 简介
- 是Pexpect库的主要对象即接口类
- 用于启动和控制子程序
3.1.2 使用流程
- 建立spawn类的实例,传入要运行的命令。
- 调用spawn类的实例方法,与子命令交互。
- 通过交互的信息,完成要实现的相关功能。
3.1.3 构造方法参数
参数 | 说明 |
---|---|
command |
任何系统可执行的命令 参数可直接放入command 不直接支持管道、通配符、标志输入、输出、错误重定向 |
args=[] |
专门将command命令的参数放入这个列表中 以 '/bin/bash',['-c','cat test | grep gree'] 形式实现管道、通配符、标志输入、输出、错误重定向等功能 |
timeout=30 | 超出时间,抛出错误 |
maxread=2000 | 从TTY读取信息最大缓冲区 |
logfile=None |
指定日志文件,可指定为sys.stdout
|
cwd=None | 指定命令运行时的当前目录 |
env=None | 指定命令运行时环境变量有哪些 |
encoding=None | 命令运行时,信息编码 |
codec_errors=‘strict’ | 编码转换时的转向 |
(1)command
>>> import pexpect
>>> child = pexpect.spawn('ls')
>>> child.expect(pexpect.EOF)
0
>>> print(child.before.decode())
get-pip.py nohup.out stop-ssl-dos.sh
index.html Python-2.7.18 ssl_flood.sh>>> child = pexpect.spawn('ls -l /home')
>>> child.expect(pexpect.EOF)
0
>>> print(child.before.decode())
total 12
drwxr-xr-x 12 root root 4096 Dec 15 14:52 files
drwxr-xr-x 10 root root 4096 Aug 13 2020 opt
drwxr-xr-x 2 root root 4096 Jul 27 2017 users# 不支持管道、通配符、标志输入、输出、错误重定向
>>> child = pexpect.spawn('ls -l | grep Python')
>>> child.expect(pexpect.EOF)
0
>>> print(child.before.decode())
/bin/ls: cannot access |: No such file or directory
/bin/ls: cannot access grep: No such file or directory
/bin/ls: cannot access Python: No such file or directory
(2)args=[]
# []传入参数列表
>>> child = pexpect.spawn('ls',args=['-l','/home'])
>>> child.expect(pexpect.EOF)
0
>>> print(child.before.decode())
total 12
drwxr-xr-x 12 root root 4096 Dec 15 14:52 files
drwxr-xr-x 10 root root 4096 Aug 13 2020 opt
drwxr-xr-x 2 root root 4096 Jul 27 2017 users# 实现管道、通配符、标志输入、输出、错误重定向等功能
>>> child = pexpect.spawn('/bin/bash',['-c','ls -al | grep Python'])
>>> child.expect(pexpect.EOF)
0
>>> print(child.before.decode())
drwxr-xr-x 18 1000 1000 4096 Feb 9 20:31 Python-2.7.18
(5)logfile=None
打开文件
>>> f = open('log.txt','wb')
>>> child = pexpect.spawn('ls -l /home', logfile=f)
>>> child.expect(pexpect.EOF)
0
>>> f.close()
>>> exit()[root@xxxx-2021 ~]# cat log.txt
total 12
drwxr-xr-x 12 root root 4096 Dec 15 14:52 files
drwxr-xr-x 10 root root 4096 Aug 13 2020 opt
drwxr-xr-x 2 root root 4096 Jul 27 2017 users
在终端直接显示
>>> import pexpect
>>> import sys
>>> child = pexpect.spawnu('ls -l /home', logfile=sys.stdout)
>>> child.expect(pexpect.EOF)
total 12
drwxr-xr-x 12 root root 4096 Dec 15 14:52 noah
drwxr-xr-x 10 root root 4096 Aug 13 2020 opt
drwxr-xr-x 2 root root 4096 Jul 27 2017 users
0
>>>
(6)cwd=None
>>> child = pexpect.spawnu('ls -al', logfile=sys.stdout, cwd='/home')
>>> child.expect(pexpect.EOF)
total 20
drwxr-xr-x 5 root root 4096 Jul 27 2017 .
drwxr-xr-x 28 root root 4096 Dec 16 07:56 ..
drwxr-xr-x 12 root root 4096 Dec 15 14:52 files
drwxr-xr-x 10 root root 4096 Aug 13 2020 opt
drwxr-xr-x 2 root root 4096 Jul 27 2017 users
0
>>>
3.1.4 基本属性和方法
描述 | 说明 |
---|---|
基本方法 |
expect(pattern,timeout=-1) 注:仅列出主要参数- pattern:可以为字符串、正则表达式、EOF、TIMEOUT,或者是以上类型的列表。用于匹配子命令返回结果 - 从子命令返回结果中进行匹配,若只提供字符串等非列表,匹配成功返回0;若提供列表,则返回匹配成功的列表序号;匹配失败则会引发异常; - 匹配事项: (1)匹配的方式是从返回信息中逐个字符读出进行匹配 (2)pattern为列表时,从左至右哪个最先匹配到就匹配哪个 (3)可以对结果进行多次匹配,但只能从前往后,前边已搜索匹配的内容不会再进行匹配 (4)匹配时自动应用re.DOTALL正则选项。( .+ 会匹配所有字符,.* 返回空字符)。(5)匹配行尾用 '\r\n' (无法用$ 匹配行尾)- timeout默认为-1时,使用默认的超时期限;设置为None时,将阻塞至返回信息
|
基本属性 |
before:匹配点之前的文本 after:匹配成功的内容 match:已匹配的匹配对象,匹配失败为None |
特殊匹配 |
pexpect.EOF pexpect.TIMEOUT 它们实际是两个异常类 |
(1)expect()连续匹配
# 连续匹配
>>> child = pexpect.spawn('ls -l')
>>> child.expect(pexpect.EOF)
0
>>> print(child.before)
total 8
-rw-r--r-- 1 root root 0 Feb 21 19:18 log.txt
drwxr-xr-x 2 root root 4096 Feb 21 19:18 test
drwxr-xr-x 2 root root 4096 Feb 21 19:19 tttt>>>
>>> child = pexpect.spawn('ls -l')
>>> child.expect('test')
0
>>> print(child.after)
test
>>> child.expect('ttt')
0
>>> print(child.after)
ttt
>>># 连续匹配 列表形式
>>> child = pexpect.spawn('ls -l')
>>> child.expect('test')
0
>>> print(child.after)
test
>>> child.expect('ttt')
0
>>> print(child.after)
ttt
>>>
>>> child = pexpect.spawn('ls -l')
>>> child.expect('test')
0
>>> child.expect(['test','ttt'])
1 # 1为ttt的列表索引,因为此前已经匹配过test,文件游标不会再匹配(test在前,tttt在后)
>>>
(2)sendline(s=’’)
bash展示
[root@xxxx-2021 ~]# nslookup
> https://www.jd.com/
Server: 10.138.48.2
Address: 10.138.48.2#53Non-authoritative answer:
*** Can't find https://www.jd.com/: No answer
>
使用sendline实现以上命令行功能:
>>> import pexpect
>>> child = pexpect.spawn('nslookup')
>>> child.expect('>')
0
>>> child.sendline('https://www.jd.com/')
20
>>> child.expect('>')
0
>>> print(child.before.decode())https://www.jd.com/
Server: 10.138.48.2
Address: 10.138.48.2#53Non-authoritative answer:
*** Can't find https://www.jd.com/: No answer>>>
3.1.5 其他发送信息的方法
方法 | 描述 |
---|---|
send(s) |
类似于sendline(),只发送字符串给子程序; 不添加回车符(换行符); 打开了日志,则会添加到日志中; 返回已发送字节数; |
write(s) | 同send()方法,但无返回值; |
writelines(sequense) | 调用write()方法,将序列中内容发送 |
sendcontrol(char) | 发送类似ctrl+d、ctrl+d等组合键 |
sendof() | 发送一个结束符,一般用于确认上一次发送内容缓冲结束 |
sendintr() | 发送退出信号 |
3.1.6 其他获取结果的方法
方法 | 描述 |
---|---|
expect_exact() |
用法与expect()方法相同,匹配速度更快; 除pattern不能用正则表达式 |
expect_list() |
匹配列表只用已编译正则表达式和EOF、TIMEOUT; 提高匹配速度; expect()方法是通过它工作的 |
read(size=-1) |
从子程序输出中读取指定量数据。 size为-1时读取时直到EOF(当子程序退出后使用) |
readline(size=-1) |
-1时直接读取一行数据; 0时返回为空; 其他值时被忽略,返回一行; |
# send方法
>>> child = pexpect.spawn('nslookup')
>>> child.expect('>')
0
>>> child.send('www.baidu.com')
13
>>> child.send('\n')
1
>>> child.expect('>')
0
>>> print(child.before.decode())www.baidu.com
Server: 10.138.48.2
Address: 10.138.48.2#53Non-authoritative answer:
www.baidu.com canonical name = www.xxx.com.
Name: www.xxx.com
Address: 100.59.200.6
Name: www.xxx.com
Address: 100.59.200.7# write方法
child.write('www.baidu.com\n')# writelines方法
child.writelines(['www.baidu.com','\n'])# sendintr方法 -- False表示子程序已经结束了
>>> child.sendintr()
>>> child.isalive()
False
3.1.7 其他常用方法
方法 | 描述 |
---|---|
compile_pattern_list(patterns) |
编译列表每一项的正则表达式; 当多次应用expect匹配时,每次会先对其列表实行编译后匹配; 为了提高效率,可以预先调用它进行编译; 之后直接使用expect_list()方法进行匹配 |
eof() | 抛出过EOF错误,则返回真。 |
interact(escape_character=’\x\d’, input_filter=None, output_filter=None) |
实现子程序和用户直接交互; 开启了日志,输入和输出会记录在日志文件中; input_filter和output_filter用于对输入和输出进行过滤;传入的应是接受字符串参数并返回字符串的一个函数; 默认退出键为 ctrl+]
|
3.1.8 控制子程序方法
方法 | 描述 |
---|---|
kill(sig) | 通过给子程序发送信号(signal); |
3.2 run函数
四、Pexpect封装工具
#!/usr/bin/env python
# -*- coding: utf-8 -*-'''
登录ssh并执行命令,端口为默认ssh端口
'''
try:import pexpect
except:import osimport sysif sys.version_info < (3, 0):os.system("pip2 install pexpect")else:print "using python 2.X."import pexpect
import rePROMPT = ['#', '>>>', '>', '\$']class SSHOpreator:def __init__(self, user, host, pwd):self.user = userself.host = hostself.pwd = pwdself.ssh = Nonedef send_command(self, cmd):# 执行命令,并返回结果self.ssh.sendline(cmd) # 传递命令self.ssh.buffer = ""self.ssh.expect(PROMPT) # 期望获得的命令提示符return self.ssh.before # 获取远程打印命令def close(self):self.ssh.close()def connect(self):ssh_newkey = "Are you sure you want to continue connecting"constr = "ssh " + self.user + "@" + self.hostself.ssh = pexpect.spawn(constr)ret = self.ssh.expect([pexpect.TIMEOUT, ssh_newkey, '[P|p]assword:'])if ret == 0:return False, '[%s@%s] Error Connecting' % (self.user, self.host)if ret == 1:self.ssh.sendline("yes") # 发送YESret = self.ssh.expect([pexpect.TIMEOUT, ssh_newkey, '[P|p]assword:'])if ret == 0:return False, '[%s@%s] Error Connecting' % (self.user, self.host)self.ssh.sendline(self.pwd)self.ssh.expect(PROMPT)return True, '[%s@%s] success Connecting' % (self.user, self.host)if __name__ == "__main__":ssh = SSHOpreator(user='root', host='127.0.0.1', pwd='123456')ret, msg = ssh.connect()if not ret:print msgexit(0)cmd = "cd /home/mydir"result = ssh.send_command(cmd)cmd = "ll"result = ssh.send_command(cmd)result = re.sub('[\s]+', ' ', result)ssh.close()print result
Python模块之pexpect详解相关推荐
- python打包安卓的方法_打包发布Python模块的方法详解
前言 昨天把自己的VASP文件处理库进行了打包并上传到PyPI,现在可以直接通过pip和easy_install来安装VASPy啦(同时欢迎使用VASP做计算化学的童鞋们加星和参与进来), 由于自己的 ...
- python解析器打包_打包发布Python模块的方法详解
前言 昨天把自己的VASP文件处理库进行了打包并上传到PyPI,现在可以直接通过pip和easy_install来安装VASPy啦(同时欢迎使用VASP做计算化学的童鞋们加星和参与进来), 由于自己的 ...
- python pexpect_Python之pexpect详解
一.引子 Pexpect程序主要用于人机对话的模拟,就是那种系统提问,人来回答yes/no,或者账号登陆输入用户名和密码等等的情况.因为这种情况特别多而且繁琐,所以很多语言都有各种自己的实现.最初的第 ...
- python模块之psutil详解
一.psutil模块: 1.psutil是一个跨平台库(http://pythonhosted.org/psutil/)能够轻松实现获取系统运行的进程和系统利用率(包括CPU.内存.磁盘.网络等)信息 ...
- python导入模块的变量_python 环境变量和import模块导入方法(详解)
1.定义 模块:本质就是.py结尾的文件(逻辑上组织python代码)模块的本质就是实现一个功能 文件名就是模块名称 包: 一个有__init__.py的文件夹:用来存放模块文件 2.导入模块 for ...
- python的socket模块_Python socket模块方法实现详解
这篇文章主要介绍了python socket模块方法实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 socket ssh (不带防止粘包的方 ...
- python标准类型内建模块_Python内建模块struct实例详解
本文研究的主要是Python内建模块struct的相关内容,具体如下. Python中变量的类型只有列表.元祖.字典.集合等高级抽象类型,并没有像c中定义了位.字节.整型等底层初级类型.因为Pytho ...
- 合法的python变量名import_python 环境变量和import模块导入方法(详解)
1.定义 模块:本质就是.py结尾的文件(逻辑上组织python代码)模块的本质就是实现一个功能 文件名就是模块名称 包: 一个有__init__.py的文件夹:用来存放模块文件 2.导入模块 imp ...
- python xlrd课程_python中xlrd模块的使用详解
一.xlrd的安装 打开cmd输入pip install xlrd安装完成即可 二.xlrd模块的使用 下面以这个工作簿为例 1.导入模块 import xlrd 2.打开工作薄 # filename ...
最新文章
- apple个人开发者证书无线发布app的实现(转)
- iOS6.0 xcode4.5 设置横屏
- 【ABAP增强】基于源代码的增强
- linux环境下java开发_Linux Ubuntu系统下Java开发环境搭建
- 动态添加JavaScript
- mongodb之配置
- 黑马程序员_Java学习日记 num1
- Numpy 新手教程(2)
- app.vue里使用data_在电脑使用讯飞有声,通过python自动化朗读
- 怎么用计算机求浮动额,2015计算机一级考试MSOFFICE上机综合训练(5)
- 当前主流读取Excel技术对比
- 化学人学python有前途吗-从化学实验室到数据分析师,月薪翻倍后的转行经验总结!...
- 基于springboot+vue的医院预约系统(前后端分离)
- php的curl函数模拟post、get数据提交,速度非常慢的处理办法
- 用PHP实现手机对jar,jad文件的下载(转)
- LSB 图像隐写与提取算法
- 经典~吸引力法则:你相信什么,就会吸引什么,获得什么
- 魔板游戏java_java魔板游戏 动物换位 俄罗斯方块
- 插值法绘制山区地貌图和等高线
- hourglass论文_论文笔记 Stacked Hourglass Networks for Human Pose Estimation