Python的Pexpect模块详解

对于存在交互过程的远程访问,如ssh, ftp, mencoder, passwd等,通过Pexpect模块可以根据应用的输出控制交互过程,从而提高容错性。
Pexpect模块首先通过生成子应用以代理交互应用,这样就可以通过检测子应用的模式匹配情况以响应交互应用的输出。

作为Don Libes的Expect实现之一,Pexpect模块是一个纯Python实现。

Python也有其他的类Expect模块,但是这些模块往往依赖于TCL和Expect扩展模块,或编译时依赖于C扩展模块。而Pexpect模块除了基于Python标准库中的pty模块之外,完全独立。从Pexpect 4.0开始,Pexpect模块可运行于Windows系统和POSIX系统。当然,由于pexpect.spawn()和pexpect.run()依赖于Python标准库中的pty模块,而pty模块只在POSIX系统中存在,所以Windows系统上的功能有限。

1. Pexpect模块的安装:
Python 3.3或Python 2.7以上
pip install pexpect
2. Pexpect模块的组成:

1) pexpect.run()函数

该函数执行一个命令并返回命令的结果,可用以替代os.system()。

pexpect.run('ls -la')


2) pexpect.SpawnBase类

抽象基类,永远不能直接实例化。其中定义的主要属性和方法如下:

  • self.before = None
  • self.after = None
  • def expect(self, pattern, timeout=-1, searchwindowsize=-1, async_=False, **kw)

3) pexpect.spawn类

继承自SpawnBase类。用法如下:

child = pexpect.spawn('/usr/bin/ftp')
child = pexpect.spawn('/usr/bin/ssh user@example.com')
child = pexpect.spawn('ls -latr /tmp')
child = pexpect.spawn('/usr/bin/ftp', [])
child = pexpect.spawn('/usr/bin/ssh', ['user@example.com'])
child = pexpect.spawn('ls', ['-latr', '/tmp'])
仔细观察上述语句,给出了两种创建子应用的方式。

再如:

child = pexpect.spawn('/bin/bash -c "ls -l | grep LOG > logs.txt"')
child.expect(pexpect.EOF)
等价于
child = pexpect.spawn('/bin/bash', ['-c', 'ls -l | grep LOG > logs.txt'])
child.expect(pexpect.EOF)

  • expect()方法

下面就可以对子应用调用方法,检测交互过程的输出并进行相应的输入。

import pexpect
ssh_client = pexpect.spawn("ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 2211 user@host")
ssh_client.expect(...)
expect()方法是最常用的方法之一,等待子应用返回指定的字符串。expect()方法的特性如下:

    • Pexpect一次从子应用中读取一个字符,所以在字符模式中,$符号不能匹配为行末或字符串结尾。
    • 要匹配行末使用'\r\n',这适合Windows系统和POSIX系统。
    • expect()返回被匹配的字符模式的序号,从0开始
    • 最少匹配原则
ssh_client.expect ('.+')#只匹配一个.
ssh_client.expect ('.*')#什么都不匹配
    • 如果没有任何字符模式被匹配,将抛出超时异常,默认超时时间为30s
ssh_client.expect (['Permission denied', 'Terminal type', '[#\$] '], timeout=60)#超时时间60s
ssh_client.expect (['Permission denied', 'Terminal type', '[#\$] '], timeout=None)#永不超时
  • 子应用在每次expect()调用的前后,子应用输出的文本分别写入到before和after属性
ssh_client.before属性,包含子应用输出的文本,直到出现了期望的字符串
ssh_client.after属性,包含匹配了的字符串

  • send()

写入一个字符串到子应用

  • sendline()
写入一行到子应用
  • logfile属性

ssh_client.logfile = sys.stdout#将日志输出到控制台

3) pexpect.EOF类
默认遇到子应用的EOF,expect()会抛出异常
4) pexpect.TIMEOUT类

index = p.expect(['good', 'bad', pexpect.EOF, pexpect.TIMEOUT])
if index == 0:
    do_something()
elif index == 1:
    do_something_else()
elif index == 2:
    do_some_other_thing()
elif index == 3:
    do_something_completely_different()

参考链接:

https://pypi.python.org/pypi/pexpect/
https://pexpect.readthedocs.io/en/stable/
https://pexpect.readthedocs.io/en/stable/api/index.html
https://github.com/pexpect/pexpect


  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
pexpectPython语言中的一个第三方模块,用于控制和自动化操作控制台或终端程序。它可以实现自动输入命令、自动应答、自动化交互式控制等功能,适用于自动化测试、批量操作等场景。 pexpect模块的常用类和方法包括: - spawn类:用于启动一个子进程并连接到其标准输入、输出和错误输出,可以在子进程中执行命令。 - expect方法:等待子进程输出特定的字符串或正则表达式,并返回匹配的字符串。 - send方法:向子进程发送字符串或命令。 - interact方法:进入交互模式,允许用户手动输入和输出。 - timeout属性:设置expect方法等待子进程输出的超时时间。 下面是一个示例代码,演示了如何使用pexpect模块连接到telnet服务器,并执行登录和命令操作: ``` import pexpect host = '127.0.0.1' port = 23 user = 'user' password = 'password' command = 'ls' # 启动telnet进程 child = pexpect.spawn('telnet %s %d' % (host, port)) # 等待登录提示 child.expect('login:') # 发送用户名 child.sendline(user) # 等待密码提示 child.expect('Password:') # 发送密码 child.sendline(password) # 等待登录成功提示 child.expect('$') # 发送命令 child.sendline(command) # 等待命令输出 child.expect('$') # 输出命令结果 print(child.before.decode()) # 退出交互模式 child.interact() ``` 这段代码中,使用spawn类启动一个telnet子进程,并通过expect和send方法实现自动登录和执行命令。最后使用interact方法进入交互模式,允许用户手动操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值