美文网首页
pexpect 跨平台(WIN、LINUX)简明教程

pexpect 跨平台(WIN、LINUX)简明教程

作者: python开发运维小队 | 来源:发表于2020-04-23 12:00 被阅读0次

    //by Chaos
    谢绝转载

    详细的内容可以参考下面的参考文档,下面的内容主要是为网络设备运维人员使用的pexpect 跨平台简明教程。

    基本概念:

    pexpect是什么

    Expect 程序主要用于人机对话的模拟,就是那种系统提问,人来回答 yes/no ,或者账号登录输入用户名和密码等等的情况。
    pexpect是 Don Libes 的 Expect 语言的一个 Python 实现,是一个用来启动子程序,并使用正则表达式对程序输出做出特定响应,以此实现与其自动交互的 Python 模块。它可以用来实现与ssh, ftp, telnet等程序的自动交互。

    pexpect主要模块

    • pexpect.spawn 创建一个子程序child,执行一个程序
    • child.sendline(或send)是在子程序中输入command,用 send 方法来发送字符串给这个程序
    • child.expect用 expect 来等待指定的关键字,这个关键字是被执行的程序打印到标准输出上面的

    child.buffer child.before child.after

    send命令后执行结果内容保存在buffer中,这时child.expect('keyword')后,child.before即为“keyword”之前的字符串,child.after即为匹配的”keyword”字符串。
    command的执行结果都保存在一个buffer中,每次执行expect时都从buffer中开始检查匹配的pattern,如果找到了匹配的pattern,则所有在匹配处之前的内容都从buffer中清除。
    (这边没有看明白也没有关系,可以看后面的实践篇例子)

    一些需要强调的细节

    跨平台使用

    通常维护人员有的偏向于用WIN系统,有的偏向于LINUX系统。所以前期团队希望形成一个统一框架的时候就出现了一个难题。框架如何适用于不同的系统。
    LInux系统pexpect包,win系统前期尝试使用winpexpect,但是程序改动很大,并没有调试成功。
    如何在WIN系统使用python的pexpect包很难找到相关资料,某乎上都是类似的疑问没有解答。
    团队成员增加后,终于有了新的思路 ,团结就是力量

            #linux系统采用以下判断
            if sys.platform.startswith('linux'):
                print("sys.platform=linux.connect()")
                tiaoban = 'ssh -o KexAlgorithms=diffie-hellman-group14-sha1 -o StrictHostKeyChecking=no -v'+TbUser+'@跳板机ip -p 跳板机端口'
                child = pexpect.spawn(tiaoban)
            # win系统采用以下判断
            elif sys.platform.startswith('win'):
                print("sys.platform=windows.connect()")
                tiaoban = 'plink.exe -ssh -v '+TbUser+'@跳板机ip -p 跳板机端口
                child = pexpect.popen_spawn.PopenSpawn(tiaoban)
                index = child.expect(["y/n", "assword:"])
    

    通过这个模块进行不同系统的适配。
    将plink.exe装在python的文件夹在python的安装目录下,win系统可以同样使用pexpect模块

    参考信息1:Pexpect 官方文档 New in version 4.0: Windows support。Pexpect can be used on Windows to wait for a pattern to be produced by a child process, using [pexpect.popen_spawn.PopenSpawn]
    参考信息2:PuTTY是一个Telnet、SSH、rlogin、纯TCP以及串行接口连接软件。plink是可以独立使用的exe实现形式,可以让我们直接在命令行制定好命令,然后执行,完成后自动关闭session。ssh是一个安全通道协议。plink是这个通道协议的一个实现 [图片上传中...(image.png-572001-1587612890428-0)]

    sendline() 和 send()

    从官方文档来看,
    sendline() 和 send() 唯一的区别就是在发送的字符串后面加上了回车换行符,这也使它们用在了不同的地方:
    只需要发送字符就可以的话用send()
    如果发送字符后还要回车的话,就用 sendline()
    但是在调测过程中,WIN系统下命令输入后,child.before始终得不到预想中的结果。
    经过逐步排查,发现在WIN系统下只能使用send() ,如果使用sendline() ,第一次交互没有问题,后续交互就开始问题。

    WIN系统下child.before输出类型

    WIN系统下child.before输出为b'byte型,做判断时要转为str型。具体可以参考最后面一篇讲编码类型的文章,讲的很详细。

    child.before.decode(encoding="ascii")
    

    child.before child.after实践

    例子1

            child.sendline('%s' % dev)
            index=child.expect(['me:','in:'])
            child.send(MANUser + '\r')
            child.expect('assword:')
            child.send(MANPass + '\r')
            child.expect(['>', '#'])
            print("login succ!")
    

    send Username后,child.before一直到'Tac_Userna',child.after为‘me:’,child.buffer为空。


    send Username后.png

    expect关键字assword:后,child.before回显一直到keyword之前,child.after为keyword,child.buffer为空。


    expect关键字assword:后.png
    expect关键字#后,child.before回显一直到keyword之前,child.after为keyword,child.buffer为空。
    expect关键字#后.png

    例子2

            child.send(Command+ '\r')
            child.expect('>')
    

    下发command命令,child.before维持原来的不变,expect到keyword以后,child.before变为下发command命令后的设备回显。


    Command下发.png expect关键字后.png

    参考文档

    官方文档

    探索Pexpect

    Pexpect示例及使用Tips

    Python Pexpect模块讲解

    Pexpect模块使用说明

    windows下使用plink实现全自动登陆ssh

    Python3_字符编码

    相关文章

      网友评论

          本文标题:pexpect 跨平台(WIN、LINUX)简明教程

          本文链接:https://www.haomeiwen.com/subject/ulqoihtx.html