• Python模块之pexpect 相当于shell的expect


     

     

    一、pexpect模块介绍

    Pexpect使Python成为控制其他应用程序的更好工具。可以理解为Linux下的expect的Python封装,通过pexpect我们可以实现对ssh,ftp,passwd,telnet等命令行进行自动交互,
    而无需人工干涉来达到自动化的目的

    二、Pexpect的安装

    #方法一:
    pip3 install pexpect
    
    #方法二:源码安装
    略

    三、简单示例

    复制代码
    import pexpect
    #ssh登录,账号root,主机:114.114.114.114,端口5000
    child = pexpect.spawn('/usr/binssh root@114.114.114.114 -p 5000')
    #expect方法等待子程序产生的输出,判断是否匹配定义的字符串
    child.expect('Password')
    #匹配后则发送密码串进行回应
    child.sendline('hello123')
    
    注:spawn类无法在windows下运行
    如果child.sendline('copy tftp://10.100.255.220/vip_user_list.txt flash:vip_user_list.txt')是一个下载文件命令,而下载过程又比较长,又不想将全局的timeout超时时间统一改太长?
    解决方法如下:
    child.timeout=1200  #超时时间12分钟
    child.send(下载文件)
    chile.expect('#')
    child.timeout=30  #执行完下载命令,改回默认超时时间30秒即可
    复制代码

    四、pexpect的核心组件

      4.1 spawn类

    复制代码
    #功能:启动和控制子应用程序,以下是它的构造函数定义:
    class pexpect.spawn(command, args=[], timeout=30, maxread=2000,
    searchwindowsize=None, logfile=None, cwd=NOne, env=None, ignore_sighup=True)
    
    #各参数解析
    #1. command参数可以使任意已知的系统命令,比如:
    child = pexpect.spawn('/usr/bin/ftp')    #启动ftp客户端命令
    child = pexpect.spawn('/usr/bin/ssh root@114.114.114.114')#启动ssh远程连接命令
    child = pexpect.spawn('ls -lattr /tmp')    #运行ls显示/tmp目录内容命令
    
    #2. args=[] 当子程序需要参数时,可以使用Python列表来代替参数项,如:
    child = pexpect.spawn('/usr/bin/ftp',[])
    child = pexpect.spawn('/usr/bin/ssh',[root@114.114.114.114'])
    child = pexpect.spawn('ls ' ['-lattr' ,'/tmp'])
    
    
    #3. timeout 为等待结果的超时时间;
    #4. maxread为pexpect从终端控制台一次读取的最大字节数
    #5.searchwindowsize 为匹配缓冲区字符串的位置,默认是从开始位置匹配
    #6.logfile 为写入到日志(打开文件或者终端sys.stdout),logfile也可单独出来,如
    fout=open('mylog.txt','wb')
    child.logfile = fout    #打印到终端,child.logfile = sys.stdout打印到屏幕(在python3中,打印到屏幕需要在spawn(encodig='utf-8')指定编码类型),最后记得关掉fout.close()
    
    ps:会存在会话结束,但是保存数据或打印到终端数据不完全问题,解决办法:延长执行命令的次数,跟时间无关,即多次使用无意义的expect(),send()来让数据有足够的时间传回来保存 注:pexpect无法解析shell命令中的元字符(>,|,*),解决办法: #方法一: child = pexpect.spawn('/bin/bash -c "ls -l | grep LOG > logs.txt"') child.expect(pexpect.EOF) #方法二: shell_cmd = 'ls -l | grep LOG > logs.txt' child=pexpect.spawn('/bin/bash',['-c',shell_cmd]) child.pexpect(pexpect.EOF) ================================================================================== #expect方法 #expect定义了一个子程序的匹配规则 #方法定义: expect(pattern,timeout=-1,searchwindowsize=-1) #参数介绍 #1.pattern为字符串或正则表达式或pexpect.EOF(指向缓冲区尾部,无匹配项)或pexpect.TIMEOUT(匹配等待超时)或者前四种组成的列表,返回列表的索引值 #2.timeout为等待匹配结果的超时时间,超时会触发pexpect.TIMEOUT #3.searchwindowsize为匹配缓冲区字符串的位置,默认是从开始位置匹配 #pattern为列表的使用: #方法一: p = pexpect.spawn('xxx') index = p.expect(['good','bad',pexpect.EOF,pexpect.TIMEOUT]) if index == 0: fun1() elif index ==1: fun2() elif index ==2: fun3() elif index==3: fun4() #方法二: p = pexpect.spawn('xxx') index = p.expect(['good','bad']) try: if index ==0: fun1() elif index ==1: fun2() expect EOF: fun3() expect TIMEOUT: fun4() #expect方法里的before和after #before:保存了最近匹配成功的内容,俩次child.expect()之间的内容,不包含pattern部分 #after:保存了最近匹配成功之后的内容,即child.expect(这里面的内容) #before与after例子 import pexpect import sys dhild = pexpect.spawn('ssh root@192.168.2.1') child.expect(['password:']) child.sendline('hello123') print ('before:',child.before) print ('after:',child.after)
    ========================================================================================== #read相关方法,与expect捕捉相配套使用 send(self,s) #发送命令,不回车 sendline(self,s='') #发送命令,回车 sendcontrol(self,char) #发送控制字符,如child.sendcontrol('c')等价于‘ctrl + c’ sendeof() #发送eof
    复制代码

       4.2 run函数

    复制代码
    #run格式
    pexpect.run(command,timeout=-1,withexitstatus=False,events=None,\
                extra_args=None,logfile=None,cwd=None,env=None)
    #参数解析:
    command:系统已知命令
    event:字典,定义了expect与sendline对应关系
    
    #实例
    from pexpect import *
    child=spawn('scp foo user@example.com:.')
    child.expect('(?i)password')
    child.sendline(mypassword)
    
    #等同于
    from pexpect import *
    run('scp foo user@example.com:.',events={'(?i)password':mypassword})
    复制代码

      4.3 pxssh类

    复制代码
    #pxssh格式:
    class pexpect.pxssh.pxssh(timeout=30,maxread=2000,searchwindowsize=None,logfile=None,cwd=None,env=None)
    #常见的三种方法
    login() #建立ssh连接
    logout()    #断开连接
    prompt()    #等待系统提示符,用于度鞥带命令执行结束
    
    #pxssh例子:ssh登录设备执行命令,取回结果
    from pexpect import pxssh
    import getpass
    try:
        s=pxssh.pxssh() #创建pxssh对象
        hostname=input('hostname:').strip()
        username=input('username:').strip()
        password=getpass.getpass('password:').strip()   #接收密码输入
        s.login(hostname,username,password) #建立ssh连接
        s.sendline('uptime')    #运行uptime命令
        s.prompt()      #匹配系统提示符
        print (s.before.decode'utf-8')    #打印出现系统提示符前的命令输出
        s.sendline('ls -l')
        s.prompt()
        print (s.before.decode'utf-8')
        s.sendline('df')
        s.prompt()
        print(s.before.decode'utf-8')
        s.logout()  #断开ssh连接
    except pxssh.ExceptionPxssh as e:
        print ('pxssh failed on login.')
        print (str(e))
  • 相关阅读:
    Linux常用命令
    Linux静态函数库与动态函数库
    解决MySQL5.7的表无法插入中文的问题
    MySQL与postgreSQL在left join查询时的区别
    《刻意练习》读书笔记
    在Golang中实现与Python装饰器类似功能的方法
    项目中使用进程内缓存的一些经验及注意事项
    Golang中使用recover捕获panic的操作及遇到的一个坑
    Python与Golang中给列表中字典按照某个key排序的实现
    浅谈Python与Golang中的“延迟绑定机制”
  • 原文地址:https://www.cnblogs.com/cheyunhua/p/15827276.html
Copyright © 2020-2023  润新知