|
概述 |
例 1:ftp 的使用
本例实现了如下功能:ftp 登录到 develperWorks.ibm.com 主机上,并用二进制传输模式下载一个名叫 rmall的文件。
#!/usr/bin/env python
import pexpect
# 即将 ftp 所要登录的远程主机的域名
ipAddress = 'develperWorks.ibm.com'
# 登录用户名
loginName = 'root'
# 用户名密码
loginPassword = 'passw0rd'
# 拼凑 ftp 命令
cmd = 'ftp ' + ipAddress
# 利用 ftp 命令作为 spawn 类构造函数的参数,生成一个 spawn 类的对象
child = pexpect.spawn(cmd)
# 期望具有提示输入用户名的字符出现
index = child.expect(["(?i)name", "(?i)Unknown host", pexpect.EOF, pexpect.TIMEOUT])
# 匹配到了 "(?i)name",表明接下来要输入用户名
if ( index == 0 ):
# 发送登录用户名 + 换行符给子程序.
child.sendline(loginName)
# 期望 "(?i)password" 具有提示输入密码的字符出现.
index = child.expect(["(?i)password", pexpect.EOF, pexpect.TIMEOUT])
# 匹配到了 pexpect.EOF 或 pexpect.TIMEOUT,表示超时或者 EOF,程序打印提示信息并退出.
if (index != 0):
print "ftp login failed"
child.close(force=True)
# 匹配到了密码提示符,发送密码 + 换行符给子程序.
child.sendline(loginPassword)
# 期望登录成功后,提示符 "ftp>" 字符出现.
index = child.expect( ['ftp>', 'Login incorrect', 'Service not available',
pexpect.EOF, pexpect.TIMEOUT])
# 匹配到了 'ftp>',登录成功.
if (index == 0):
print 'Congratulations! ftp login correct!'
# 发送 'bin'+ 换行符给子程序,表示接下来使用二进制模式来传输文件.
child.sendline("bin")
print 'getting a file...'
# 向子程序发送下载文件 rmall 的命令.
child.sendline("get rmall")
# 期望下载成功后,出现 'Transfer complete.*ftp>',其实下载成功后,
# 会出现以下类似于以下的提示信息:
# 200 PORT command successful.
# 150 Opening data connection for rmall (548 bytes).
# 226 Transfer complete.
# 548 bytes received in 0.00019 seconds (2.8e+03 Kbytes/s)
# 所以直接用正则表达式 '.*' 将 'Transfer complete' 和提示符 'ftp>' 之间的字符全省去.
index = child.expect( ['Transfer complete.*ftp>', pexpect.EOF, pexpect.TIMEOUT] )
# 匹配到了 pexpect.EOF 或 pexpect.TIMEOUT,表示超时或者 EOF,程序打印提示信息并退出.
if (index != 0):
print "failed to get the file"
child.close(force=True)
# 匹配到了 'Transfer complete.*ftp>',表明下载文件成功,打印成功信息,并输入 'bye',结束 ftp session.
print 'successfully received the file'
child.sendline("bye")
# 用户名或密码不对,会先出现 'Login incorrect',然后仍会出现 'ftp>',但是 pexpect 是最小匹配,不是贪婪匹配,
# 所以如果用户名或密码不对,会匹配到 'Login incorrect',而不是 'ftp>',然后程序打印提示信息并退出.
elif (index == 1):
print "You entered an invalid login name or password. Program quits!"
child.close(force=True)
# 匹配到了 'Service not available',一般表明 421 Service not available, remote server has
# closed connection,程序打印提示信息并退出.
# 匹配到了 pexpect.EOF 或 pexpect.TIMEOUT,表示超时或者 EOF,程序打印提示信息并退出.
else:
print "ftp login failed! index = " + index
child.close(force=True)
# 匹配到了 "(?i)Unknown host",表示 server 地址不对,程序打印提示信息并退出
elif index == 1 :
print "ftp login failed, due to unknown host"
child.close(force=True)
# 匹配到了 pexpect.EOF 或 pexpect.TIMEOUT,表示超时或者 EOF,程序打印提示信息并退出
else:
print "ftp login failed, due to TIMEOUT or EOF"
child.close(force=True)
|
注: 本例 expect 函数中的 pattern 使用了 List,并包含了 pexpect.EOF和pexpect.TIMEOUT,这样出现了超时或者 EOF,不会抛出 expection 。(关于 expect() 函数的具体使用,请参阅参考资料) |
|
例 2:记录 log |
#!/usr/bin/env python """ This run a user specified command and log its result. ./command.py [-a] [-c command] {logfilename} logfilename : This is the name of the log file. Default is command.log. -a : Append to log file. Default is to overwrite log file. -c : spawn command. Default is the command 'ls -l'. Example: This will execute the command 'pwd' and append to the log named my_session.log: ./command.py -a -c 'pwd' my_session.log """ import os, sys, getopt import traceback import pexpect # 如果程序中间出错,打印提示信息后退出 def exit_with_usage(): print globals()['__doc__'] os._exit(1) def main(): ###################################################################### # Parse the options, arguments, get ready, etc. ###################################################################### try: optlist, args = getopt.getopt(sys.argv[1:], 'h?ac:', ['help','h','?']) # 如果指定的参数不是’ -a ’ , ‘ -h ’ , ‘ -c ’ , ‘ -? ’ , ‘ --help ’ , #‘ --h ’或’ --? ’时,会抛出 exception, # 这里 catch 住,然后打印出 exception 的信息,并输出 usage 提示信息. except Exception, e: print str(e) exit_with_usage() options = dict(optlist) # 最多只能指定一个 logfile,否则出错. if len(args) > 1: exit_with_usage() # 如果指定的是 '-h','--h','-?','--?' 或 '--help',只输出 usage 提示信息. if [elem for elem in options if elem in ['-h','--h','-?','--?','--help']]: print "Help:" exit_with_usage() # 获取 logfile 的名字. if len(args) == 1: script_filename = args[0] else: # 如果用户没指定,默认 logfile 的名字是 command.log script_filename = "command.log" # 如果用户指定了参数 -a,如果之前该 logfile 存在,那么接下来的内容会附加在原先内容之后, # 如果之前没有该 logfile,新建一个文件,并且接下来将内容写入到该文件中. if '-a' in options: fout = open (script_filename, "ab") else: # 如果用户没指定参数 -a,默认按照用户指定 logfile 文件名新建一个文件,然后将接下来将内容写入到该文件中. fout = open (script_filename, "wb") # 如果用户指定了 -c 参数,那么运行用户指定的命令. if '-c' in options: command = options['-c'] # 如果用户没有指定 -c 参数,那么默认运行命令'ls – l' else: command = "ls -l" # logfile 文件的 title fout.write ('==========Log Tile: IBM developerWorks China==========\n') # 为接下来的运行命令生成一个 pexpect 的 spawn 类子程序的对象. p = pexpect.spawn(command) # 将之前 open 的 file 对象指定为 spawn 类子程序对象的 log 文件. p.logfile = fout # 命令运行完后,expect EOF 出现,这时会将 spawn 类子程序对象的输出写入到 log 文件. p.expect(pexpect.EOF) #open 完文件,使用完毕后,需关闭该文件. fout.close() return 0 if __name__ == "__main__": try: main() except SystemExit, e: raise e except Exception, e: print "ERROR" print str(e) traceback.print_exc() os._exit(1)