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 >>> place('\r\n','\n'))
4总⽤量 52
5 drwxr-xr-x 2 root root 409
6 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')
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'])
child = pexpect.spawn ('ls', ['-latr', '/tmp'])
1 >>>child = pexpect.spawn('ls –l /var')
2 >>> child = pexpect.spawn('ls',['-l','/var'])
3 >>>res = adlines()
4 >>> for line in res:
5 ... print(line.strip('\r\n'))
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
writeline和write的区别python17 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 代表在等待⽬标正则表达式中出现了超时。
1try:
2 index = pect (['good', 'bad'])
3if index == 0:
4 do_something()
5elif index == 1:
6 do_something_else()
7except EOF:
8 do_some_other_thing()
9except TIMEOUT:
10 do_something_completely_different()
expect 不断从读⼊缓冲区中匹配⽬标正则表达式,当匹配结束时 pexpect 的 before 成员中保存了缓冲区中匹配成功处之前的内容, pexpect 的 after 成员保存的是缓冲区中与⽬标正则表达式相匹配的内容。
1 >>> child = pexpect.spawn('ls -l /var')
2 >>> pect(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 >>> pect('Name.*')
4 0 #只匹配⼀个正则‘Name.*’,因此返回0
5 >>> child.sendline('ftp_admin')
6 10
7 >>> pect('Password:')
8 0
9 >>> child.sendline('password')
10 9
11 >>> pect('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('','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 是不断从缓冲区中匹配,如果想匹配⾏尾不能使⽤ “$” ,只能使⽤ “\r\n”代表⼀⾏的结束。另外其只能得到最⼩匹配的结果,⽽不是进⾏贪婪匹配,例如 pect ('.+') 只能匹配到⼀个字符。
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 。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论