Pexpect 是 Don Libes 的 Expect 语言的一个 Python 实现,是一个用来启动子程序,并使用正则表达式对程序输出做出特定响应,以此实现与其自动交互的 Python 模块。 Pexpect 的使用范围很广,可以用来实现与 ssh、ftp 、telnet 等程序的自动交互;可以用来自动复制软件安装包并在不同机器自动安装;还可以用来实现软件测试中与命令行交互的自动化。Pexpect仅能在Unix/Linux平台下使用。

1.1 run函数

run(command, timeout=-1, withexitstatus=False, events=None, extra_args=None, logfile=None, cwd=None, env=None)

若不指定withexitstatus参数,则返回command执行后的返回值,若指定withexitstatus为True,则返回一个包含退出状态的元组。

 >>> res = pexpect.run('ls -l /var')
>>>(res,exitcode) = pexpect.run(‘ls –l /var’,withexitstatus=True)
>>> print(res.replace('\r\n','\n'))
总用量 52
drwxr-xr-x 2 root root 4096 9月 21 2014 agentx
drwxr-xr-x 2 root root 4096 2月 5 2015 backups
drwxr-xr-x 21 root root 4096 3月 28 2015 cache
drwxr-xr-x 71 root root 4096 3月 28 2015 lib
drwxrwsr-x 2 root staff 4096 2月 5 2015 local
lrwxrwxrwx 1 root root 9 3月 28 2015 lock -> /run/lock
drwxr-xr-x 21 root root 4096 7月 12 21:36 log
drwxrwsr-x 2 root mail 4096 2月 6 2015 mail
drwxr-xr-x 2 root root 4096 2月 6 2015 opt
lrwxrwxrwx 1 root root 4 3月 28 2015 run -> /run
drwxr-xr-x 6 root root 4096 3月 28 2015 spool
drwxrwxrwt 2 root root 4096 7月 21 20:33 tmp
drwxr-xr-x 2 root root 4096 6月 27 2013 unicornscan
drwxr-xr-x 2 root root 4096 7月 11 2015 workspace
drwxr-xr-x 2 root root 4096 3月 28 2015 www
>>>print(exitcode)
0

2. spawn类

__init__(self, command, args=[], timeout=30, maxread=2000, searchwindowsize=None, logfile=None, cwd=None, env=None)

This is the constructor. The command parameter may be a string that includes a command and any arguments to the command. For example::

child = pexpect.spawn ('/usr/bin/ftp')

child = pexpect.spawn ('/usr/bin/ssh user@example.com')

child = pexpect.spawn ('ls -latr /tmp')

You may also construct it with a list of arguments like so::

child = pexpect.spawn ('/usr/bin/ftp', [])

child = pexpect.spawn ('/usr/bin/ssh', ['user@example.com'])

child = pexpect.spawn ('ls', ['-latr', '/tmp'])

 >>>child = pexpect.spawn('ls –l /var')
>>> child = pexpect.spawn('ls',['-l','/var'])
>>>res = child.readlines()
>>> for line in res:
... print(line.strip('\r\n'))
...
总用量 52
drwxr-xr-x 2 root root 4096 9月 21 2014 agentx
drwxr-xr-x 2 root root 4096 2月 5 2015 backups
drwxr-xr-x 21 root root 4096 3月 28 2015 cache
drwxr-xr-x 71 root root 4096 3月 28 2015 lib
drwxrwsr-x 2 root staff 4096 2月 5 2015 local
lrwxrwxrwx 1 root root 9 3月 28 2015 lock -> /run/lock
drwxr-xr-x 21 root root 4096 7月 12 21:36 log
drwxrwsr-x 2 root mail 4096 2月 6 2015 mail
drwxr-xr-x 2 root root 4096 2月 6 2015 opt
lrwxrwxrwx 1 root root 4 3月 28 2015 run -> /run
drwxr-xr-x 6 root root 4096 3月 28 2015 spool
drwxrwxrwt 2 root root 4096 7月 21 20:33 tmp
drwxr-xr-x 2 root root 4096 6月 27 2013 unicornscan
drwxr-xr-x 2 root root 4096 7月 11 2015 workspace
drwxr-xr-x 2 root root 4096 3月 28 2015 www

3. spawn实例child的方法

expect(self, pattern, timeout=-1, searchwindowsize=None)

在参数中: pattern 可以是正则表达式, pexpect.EOF , pexpect.TIMEOUT ,或者由这些元素组成的列表。需要注意的是,当 pattern 的类型是一个列表时,且子程序输出结果中不止一个被匹配成功,则匹配返回的结果是缓冲区中最先出现的那个元素,或者是列表中最左边的元素。使用 timeout 可以指定等待结果的超时时间 ,该时间以秒为单位。当超过预订时间时, expect 匹配到pexpect.TIMEOUT。

expect() 在执行中可能会抛出两种类型的异常分别是 EOF and TIMEOUF,其中 EOF 通常代表子程序的退出, TIMEOUT 代表在等待目标正则表达式中出现了超时。

 try:
index = child.expect (['good', 'bad'])
if index == 0:
  do_something()
elif index == 1:
do_something_else()
except EOF:
do_some_other_thing()
except TIMEOUT:
  do_something_completely_different()

expect 不断从读入缓冲区中匹配目标正则表达式,当匹配结束时 pexpect 的 before 成员中保存了缓冲区中匹配成功处之前的内容, pexpect 的 after 成员保存的是缓冲区中与目标正则表达式相匹配的内容。

 >>> child = pexpect.spawn('ls -l /var')
>>> child.expect(pexpect.EOF)
0
>>> print child.before
总用量 52
drwxr-xr-x 2 root root 4096 9月 21 2014 agentx
drwxr-xr-x 2 root root 4096 2月 5 2015 backups
drwxr-xr-x 21 root root 4096 3月 28 2015 cache
drwxr-xr-x 71 root root 4096 3月 28 2015 lib
drwxrwsr-x 2 root staff 4096 2月 5 2015 local
lrwxrwxrwx 1 root root 9 3月 28 2015 lock -> /run/lock
drwxr-xr-x 21 root root 4096 7月 12 21:36 log
drwxrwsr-x 2 root mail 4096 2月 6 2015 mail
drwxr-xr-x 2 root root 4096 2月 6 2015 opt
lrwxrwxrwx 1 root root 4 3月 28 2015 run -> /run
drwxr-xr-x 6 root root 4096 3月 28 2015 spool
drwxrwxrwt 2 root root 4096 7月 21 20:33 tmp
drwxr-xr-x 2 root root 4096 6月 27 2013 unicornscan
drwxr-xr-x 2 root root 4096 7月 11 2015 workspace
drwxr-xr-x 2 root root 4096 3月 28 2015 www >>> print child.after
<class 'pexpect.EOF'> send(self, s)
sendline(self, s='')
sendcontrol(self, char)

这些方法用来向子程序发送命令,模拟输入命令的行为。 与 send() 不同的是 sendline() 会额外输入一个回车符 ,更加适合用来模拟对子程序进行输入命令的操作。 当需要模拟发送 “Ctrl+c” 的行为时,还可以使用 sendcontrol() 发送控制字符。

child.sendcontrol('c')             #发送crtl + c

由于 send() 系列函数向子程序发送的命令会在终端显示,所以也会在子程序的输入缓冲区中出现,因此不建议使用 expect 匹配最近一次 sendline() 中包含的字符。否则可能会在造成不希望的匹配结果。

4. ftp交互实例

 >>> import pexpect
>>> child = pexpect.spawn('ftp 192.168.1.102')
>>> child.expect('Name.*')
0 #只匹配一个正则‘Name.*’,因此返回0
>>> child.sendline('ftp_admin')
10
>>> child.expect('Password:')
0
>>> child.sendline('password')
9
>>> child.expect('ftp>')
0
>>> child.sendline('get NmapScanner.py')
19

5. pxssh类的使用

Pxssh 做为 pexpect 的派生类可以用来建立一个 ssh 连接,它相比其基类增加了如下方法:

login() 建立到目标机器的ssh连接 ;

losuckgout() 释放该连接 ;

prompt() 等待提示符,通常用于等待命令执行结束。

 >>> import pxssh
>>> s = pxssh.pxssh()
>>> s.login('xx.xx.xx.xx','root','xxxx')
True
>>> s.sendline('uptime')
7
>>> print s.before
unset PROMPT_COMMAND
[root@iZ2594ysug5Z ~]# PS1='[PEXPECT]\$ ' >>> s.prompt()
True
>>> print s.before
uptime
11:24:34 up 8 days, 21:02, 2 users, load average: 0.00, 0.00, 0.00 >>> s.logout()

在使用 expect() 时,由于 Pexpect 是不断从缓冲区中匹配,如果想匹配行尾不能使用 “$” ,只能使用 “\r\n”代表一行的结束。 另外其只能得到最小匹配的结果,而不是进行贪婪匹配,例如 child.expect ('.+') 只能匹配到一个字符。

6. logfile

logfile:

只能通过 spawn 类的构造函数指定。在 spawn 类的构造函数通过参数指定 logfile 时,表示开启或关闭 logging 。所有的子程序的 input 和 output 都会被 copy 到指定的 logfile 中。设置 logfile 为 None 表示停止 logging,默认就是停止 logging 。设置 logfile 为 sys.stdout,会将所有东西 echo 到标准输出。

logfile_read和logfile_send:

logfile_read:只用来记录 python 主程序接收到 child 子程序的输出,有的时候你不想看到写给 child 的所有东西,只希望看到 child 发回来的东西。 logfile_send:只用来记录 python 主程序发送给 child 子程序的输入 logfile、logfile_read 和 logfile_send 何时被写入呢? logfile、logfile_read 和 logfile_send 会在每次写 write 和 send 操作后被 flush 。

调用 send 后,才会往 logfile 和 logfile_send 中写入,sendline/sendcontrol/sendoff/write/writeline 最终都会调用 send,所以 sendline 后 logfile 中一定有内容了,只要此时 logfile 没有被 close 。

调用 read_nonblocking 后,才会往 logfile 和 logfile_read 中写入,expect_loop 会调用 read_nonblocking,而 expect_exact 和 expect_list 都会调用 expect_loop,expect 会调用 expect_list,所以 expect 后 logfile 中一定有内容了,只要此时 logfile 没有被 close 。

python的pexpect模块的更多相关文章

  1. python之pexpect模块

    最近在看<Python自动化运维技术与最佳实战>这本书,学到了一个运维中用到的模块:pexpect 下面是其定义: Pexpect 是一个用来启动子程序并对其进行自动控制的 Python ...

  2. [python]使用pexpect模块进行批量scp

    #!/usr/bin/env python# -*- coding: utf-8 -*- #wangxiaofei #awcloud自动化测试 import time,osimport threadi ...

  3. 8.python 系统批量运维管理器之pexpect模块

    小插曲 前几节讲了paramiko模块,但是pexpect模块的功能几乎跟paramiko一样,先来分析一下: 1.各自介绍 pexpect是一个通过启动子程序,使用正则表达式对程序输出做出特定响应, ...

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

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

  5. Pexpect模块的安装

    Pexpect模块的安装 下载地址:https://pypi.python.org/pypi/pexpect/ 解压后在目录下运行:python ./setup.py install (必须是root ...

  6. python之常用模块4

    pyinotify模块 pip3 install pyinotify pyinotify提供的事件: 事件标志 事件含义 IN_ACCESS 被监控项目或者被监控目录中的文件被访问,比如一个文件被读取 ...

  7. python的pexpect详解

    Pexpect 是一个用来启动子程序并对其进行自动控制的纯 Python 模块. Pexpect 可以用来和像 ssh.ftp.passwd.telnet 等命令行程序进行自动交互.继第一部分< ...

  8. pexpect模块

    pexpect用来启动子程序,使用正则表达式对程序输出做出特定响应,以此实现与其自动交互的python模块,当然我们可以使用他来做ssh登陆,ssh模块登陆还有一个基于python实现远程连接,用于s ...

  9. python的库有多少个?python有多少个模块?

    这里列举了大概500个左右的库: !   Chardet字符编码探测器,可以自动检测文本.网页.xml的编码. colorama主要用来给文本添加各种颜色,并且非常简单易用. Prettytable主 ...

随机推荐

  1. IOS UITest 初始化 ViewController

    import XCTest @testable import UITestDemo class UITestDemoTests: XCTestCase { var homevc:HomeViewCon ...

  2. ACdream 1135 MST

    MST Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) Problem Descrip ...

  3. Codeforces Round #438 by Sberbank and Barcelona Bootcamp (Div. 1 + Div. 2 combine

    最近只想喊666,因为我是真得菜,大晚上到网吧打代码还是很不错的嘛 A. Bark to Unlock time limit per test 2 seconds memory limit per t ...

  4. HDU-4825 Xor Sum,字典树好题!

    Xor Sum 一遍A了之后大呼一声好(keng)题!debug了两小时~~~~百度之星资格赛,可以. 题意:给你一个n个元素的数组,m次查询,每次输入一个数k要求从数组中找到一个数与k异或值最大,输 ...

  5. 【Kubernetes】声明式API与Kubernetes编程范式

    什么是声明式API呢? 答案是,kubectl apply命令. 举个栗子 在本地编写一个Deployment的YAML文件: apiVersion: apps/v1 kind: Deployment ...

  6. 总结搭建Oracle11g DG踩的坑

    此次的操作环境是Oracle11g 单实例,os为Linux,采用duplicate在线创建物理备库 primary上设置相关参数 ALTER SYSTEM SET LOG_ARCHIVE_CONFI ...

  7. 维修队列(bzoj 1500)

    Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一 ...

  8. 洛谷 P1756 最小花费

    题目背景 题目描述 在n个人中,某些人的银行账号之间可以互相转账.这些人之间转账的手续费各不相同.给定这些人之间转账时需要从转账金额里扣除百分之几的手续费,请问A最少需要多少钱使得转账后B收到100元 ...

  9. bootstrap-datatables

    刚写到datatimepicker的时候想到这个问题. 这可以说是我接触到的第一个功能如此齐全的一款依赖型插件.我把依赖于别人库的插件这么称呼. 首先上官网:http://datatables.clu ...

  10. Linux c内存泄漏检测

    在Linux下些C语言程序,最大的问题就是没有一个好的编程IDE,当然想kdevelop等工具都相当的强大,但我还是习惯使用kdevelop工具,由于没有一个习惯的编程IDE,内存检测也就成了在Lin ...