zoukankan      html  css  js  c++  java
  • python的pexpect模块

        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,则返回一个包含退出状态的元组。

     1 >>> res = pexpect.run('ls -l /var') 
     2 >>>(res,exitcode) = pexpect.run(‘ls –l /var’,withexitstatus=True)
     3 >>> print(res.replace('
    ','
    '))
     4 总用量 52
     5 drwxr-xr-x  2 root root  4096  9月 21  2014 agentx
     6 drwxr-xr-x  2 root root  4096  2月  5  2015 backups
     7 drwxr-xr-x 21 root root  4096  3月 28  2015 cache
     8 drwxr-xr-x 71 root root  4096  3月 28  2015 lib
     9 drwxrwsr-x  2 root staff 4096  2月  5  2015 local
    10 lrwxrwxrwx  1 root root     9  3月 28  2015 lock -> /run/lock
    11 drwxr-xr-x 21 root root  4096  7月 12 21:36 log
    12 drwxrwsr-x  2 root mail  4096  2月  6  2015 mail
    13 drwxr-xr-x  2 root root  4096  2月  6  2015 opt
    14 lrwxrwxrwx  1 root root     4  3月 28  2015 run -> /run
    15 drwxr-xr-x  6 root root  4096  3月 28  2015 spool
    16 drwxrwxrwt  2 root root  4096  7月 21 20:33 tmp
    17 drwxr-xr-x  2 root root  4096  6月 27  2013 unicornscan
    18 drwxr-xr-x  2 root root  4096  7月 11  2015 workspace
    19 drwxr-xr-x  2 root root  4096  3月 28  2015 www
    20 >>>print(exitcode)
    21 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'])

     

     1 >>>child = pexpect.spawn('ls –l /var')
     2 >>> child = pexpect.spawn('ls',['-l','/var'])
     3 >>>res = child.readlines()
     4 >>> for line in res:
     5 ...     print(line.strip('
    '))
     6 ... 
     7 总用量 52
     8 drwxr-xr-x  2 root root  4096  9月 21  2014 agentx
     9 drwxr-xr-x  2 root root  4096  2月  5  2015 backups
    10 drwxr-xr-x 21 root root  4096  3月 28  2015 cache
    11 drwxr-xr-x 71 root root  4096  3月 28  2015 lib
    12 drwxrwsr-x  2 root staff 4096  2月  5  2015 local
    13 lrwxrwxrwx  1 root root     9  3月 28  2015 lock -> /run/lock
    14 drwxr-xr-x 21 root root  4096  7月 12 21:36 log
    15 drwxrwsr-x  2 root mail  4096  2月  6  2015 mail
    16 drwxr-xr-x  2 root root  4096  2月  6  2015 opt
    17 lrwxrwxrwx  1 root root     4  3月 28  2015 run -> /run
    18 drwxr-xr-x  6 root root  4096  3月 28  2015 spool
    19 drwxrwxrwt  2 root root  4096  7月 21 20:33 tmp
    20 drwxr-xr-x  2 root root  4096  6月 27  2013 unicornscan
    21 drwxr-xr-x  2 root root  4096  7月 11  2015 workspace
    22 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 代表在等待目标正则表达式中出现了超时。

     1 try:
     2     index = child.expect (['good', 'bad'])
     3     if index == 0:
     4       do_something()
     5     elif index == 1:
     6        do_something_else()
     7     except EOF:
     8        do_some_other_thing()
     9 except TIMEOUT:
    10   do_something_completely_different()

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

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

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

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

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

    4. ftp交互实例

     1 >>> import pexpect
     2 >>> child = pexpect.spawn('ftp 192.168.1.102')
     3 >>> child.expect('Name.*')
     4 0        #只匹配一个正则‘Name.*’,因此返回0
     5 >>> child.sendline('ftp_admin')
     6 10
     7 >>> child.expect('Password:')
     8 0
     9 >>> child.sendline('password')
    10 9
    11 >>> child.expect('ftp>')
    12 0
    13 >>> child.sendline('get NmapScanner.py')
    14 19

    5. pxssh类的使用

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

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

    losuckgout() 释放该连接 ;

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

     1 >>> import pxssh
     2 >>> s = pxssh.pxssh()
     3 >>> s.login('xx.xx.xx.xx','root','xxxx')
     4 True
     5 >>> s.sendline('uptime')
     6 7
     7 >>> print s.before
     8  unset PROMPT_COMMAND
     9 [root@iZ2594ysug5Z ~]# PS1='[PEXPECT]$ '
    10 
    11 >>> s.prompt()
    12 True
    13 >>> print s.before
    14 uptime
    15  11:24:34 up 8 days, 21:02,  2 users,  load average: 0.00, 0.00, 0.00
    16 
    17 >>> s.logout()

    在使用 expect() 时,由于 Pexpect 是不断从缓冲区中匹配,如果想匹配行尾不能使用 “$” ,只能使用 “ ”代表一行的结束。 另外其只能得到最小匹配的结果,而不是进行贪婪匹配,例如 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 。

  • 相关阅读:
    第十四周学习进度
    二阶段冲刺(七)
    二阶段冲刺(六)
    二阶段冲刺(五)
    二阶段冲刺(四)
    二阶段冲刺(三)
    二阶段冲刺(二)
    二阶段冲刺(一)
    第十三周学习进度
    linux初级学习笔记二:linux操作系统及常用命令,文件的创建与删除和命名规则,命令行展开以及linux中部分目录的作用!(视频序号:02_3)
  • 原文地址:https://www.cnblogs.com/darkpig/p/5717902.html
Copyright © 2011-2022 走看看