来谈谈:python Pexpect
小知识:如果说Ubuntu是现今最受桌面用户欢迎的Linux操作系统,那么CentOS就是最受公司、企业、IDC喜爱的Linux发行版了。Pexpect是一个用来启动子步伐并对其举行主动把持的纯Python模块。Pexpect能够用来和像ssh、ftp、passwd、telnet等下令路程序举行主动交互。继第一部分《探究Pexpect,第1部分:分析Pexpect》先容了Pexpect的基本和怎样利用后,本文将分离详细实例动手,具体先容Pexpect的用法和在实践使用中的注重点。概述
经由过程本系列第一部分《探究Pexpect,第1部分:分析Pexpect》(请参阅参考材料)的先容,信任人人已对Pexpect的用法已有了对照周全的懂得,晓得Pexpect是个纯Python言语完成的模块,利用其能够轻松便利的完成与ssh、ftp、passwd和telnet等步伐的主动交互,可是读者的了解还大概只是停止在实际基本上,本文将从实践例子动手详细先容Pexpect的利用场景和利用心得体验,实例中的代码读者都能够间接拿来利用,信任会对人人发生对照年夜的匡助。以下是本文所要先容的一切Pexpect例子题目:
[*]例1:ftp的利用(注:spawn、expect和sendline的利用)
[*]例2:纪录log(注:logfile、logfile_send和logfile_read的利用)
[*]例3:ssh的利用
[*]例4:pxssh的利用
[*]例5:telnet的利用(注:interact的利用)
[*]pexpect利用tips
[*]调试pexpect步伐的tips
[*]pexpect不会注释shell中的元字符
[*]EOF非常和TIMEOUT非常
[*]利用run()来替换某些的spawn的利用
[*]expect_exact()的利用
[*]expect()中正则表达式的利用tips
[*]isalive()的利用tips
[*]delaybeforesend的利用tips
http://www.centoscn.com/uploads/allimg/130726/0050451b8-0.gif
http://www.centoscn.com/uploads/allimg/130726/005045D64-1.gif
回页首
例1:ftp的利用
本例完成了以下功效:ftp登录到develperWorks.ibm.com主机上,并用二进制传输形式下载一个名叫rmall的文件。
清单1.ftp的例子代码
#!/usr/bin/envpythonimportpexpect#行将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)Unknownhost",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"ftploginfailed"child.close(force=True)#婚配到了暗码提醒符,发送暗码+换行符给子步伐.child.sendline(loginPassword)#希冀登录乐成后,提醒符"ftp>"字符呈现.index=child.expect()#婚配到了ftp>,登录乐成.if(index==0):printCongratulations!ftplogincorrect!#发送bin+换行符给子步伐,暗示接上去利用二进制形式来传输文件.child.sendline("bin")printgettingafile...#向子步伐发送下载文件rmall的下令.child.sendline("getrmall")#希冀下载乐成后,呈现Transfercomplete.*ftp>,实在下载乐成后,#会呈现以下相似于以下的提醒信息:#200PORTcommandsuccessful.#150Openingdataconnectionforrmall(548bytes).#226Transfercomplete.#548bytesreceivedin0.00019seconds(2.8e+03Kbytes/s)#以是间接用正则表达式.*将Transfercomplete和提醒符ftp>之间的字符全省往.index=child.expect()#婚配到了pexpect.EOF或pexpect.TIMEOUT,暗示超时大概EOF,步伐打印提醒信息并加入.if(index!=0):print"failedtogetthefile"child.close(force=True)#婚配到了Transfercomplete.*ftp>,标明下载文件乐成,打印乐成信息,并输出bye,停止ftpsession.printsuccessfullyreceivedthefilechild.sendline("bye")#用户名或暗码不合错误,会先呈现Loginincorrect,然后仍会呈现ftp>,可是pexpect是最小婚配,不是贪心婚配,#以是假如用户名或暗码不合错误,会婚配到Loginincorrect,而不是ftp>,然后步伐打印提醒信息并加入.elif(index==1):print"Youenteredaninvalidloginnameorpassword.Programquits!"child.close(force=True)#婚配到了Servicenotavailable,一样平常标明421Servicenotavailable,remoteserverhas#closedconnection,步伐打印提醒信息并加入.#婚配到了pexpect.EOF或pexpect.TIMEOUT,暗示超时大概EOF,步伐打印提醒信息并加入.else:print"ftploginfailed!index="+indexchild.close(force=True)#婚配到了"(?i)Unknownhost",暗示server地点不合错误,步伐打印提醒信息并加入elifindex==1:print"ftploginfailed,duetounknownhost"child.close(force=True)#婚配到了pexpect.EOF或pexpect.TIMEOUT,暗示超时大概EOF,步伐打印提醒信息并加入else:print"ftploginfailed,duetoTIMEOUTorEOF"child.close(force=True)
注:
[*]运转后,输入了局为:
Congratulations!ftplogincorrect!gettingafile...successfullyreceivedthefile
[*]本例expect函数中的pattern利用了List,并包括了pexpect.EOF和pexpect.TIMEOUT,如许呈现了超时大概EOF,不会抛出expection。(关于expect()函数的详细利用,请参阅参考材料)
[*]假如步伐运转两头呈现了毛病,如用户名暗码毛病,超时大概EOF,近程server毗连不上,城市利用child.close(force=True)关失落ftp子步伐。挪用close能够用来封闭与子步伐的connection毗连,假如你不但想封闭与子步伐的毗连,还想确保子步伐是真的被terminate停止了,设置参数force=True,其终极会挪用child.kill(signal.SIGKILL)来杀失落子步伐。
http://www.centoscn.com/uploads/allimg/130726/0050451b8-0.gif
http://www.centoscn.com/uploads/allimg/130726/005045D64-1.gif
回页首
例2:纪录log
本例完成了以下功效:运转一个下令,并将该下令的运转输入了局纪录到log文件中./command.py[-a][-ccommand]{logfilename}-c后接的是要运转的下令的名字,默许是“ls-l”;logfilename是纪录下令运转了局的log文件名,默许是“command.log”;指定-a暗示下令的输入了局会附加在logfilename后,假如logfilename之前已存在的话。
清单2.纪录log的例子代码
#!/usr/bin/envpython"""Thisrunauserspecifiedcommandandlogitsresult../command.py[-a][-ccommand]{logfilename}logfilename:Thisisthenameofthelogfile.Defaultiscommand.log.-a:Appendtologfile.Defaultistooverwritelogfile.-c:spawncommand.Defaultisthecommandls-l.Example:Thiswillexecutethecommandpwdandappendtothelognamedmy_session.log:./command.py-a-cpwdmy_session.log"""importos,sys,getoptimporttracebackimportpexpect#假如步伐两头堕落,打印提醒信息前进出defexit_with_usage():printglobals()os._exit(1)defmain():#######################################################################Parsetheoptions,arguments,getready,etc.######################################################################try:optlist,args=getopt.getopt(sys.argv,h?ac:,)#假如指定的参数不是’-a’,‘-h’,‘-c’,‘-?’,‘--help’,#‘--h’或’--?’时,会抛出exception,#这里catch住,然后打印出exception的信息,并输入usage提醒信息.exceptException,e:printstr(e)exit_with_usage()options=dict(optlist)#最多只能指定一个logfile,不然堕落.iflen(args)>1:exit_with_usage()#假如指定的是-h,--h,-?,--?或--help,只输入usage提醒信息.if]:print"Help:"exit_with_usage()#猎取logfile的名字.iflen(args)==1:script_filename=argselse:#假如用户没指定,默许logfile的名字是command.logscript_filename="command.log"#假如用户指定了参数-a,假如之前该logfile存在,那末接上去的内容会附加在本来内容以后,#假如之前没有该logfile,新建一个文件,而且接上去将内容写进到该文件中.if-ainoptions:fout=open(script_filename,"ab")else:#假如用户没指定参数-a,默许依照用户指定logfile文件名新建一个文件,然后将接上去将内容写进到该文件中.fout=open(script_filename,"wb")#假如用户指定了-c参数,那末运转用户指定的下令.if-cinoptions:command=options[-c]#假如用户没有指定-c参数,那末默许运转下令ls–lelse:command="ls-l"#logfile文件的titlefout.write(==========LogTile:IBMdeveloperWorksChina==========
)#为接上去的运转下令天生一个pexpect的spawn类子步伐的工具.p=pexpect.spawn(command)#将之前open的file工具指定为spawn类子步伐工具的log文件.p.logfile=fout#下令运转完后,expectEOF呈现,这时候会将spawn类子步伐工具的输入写进到log文件.p.expect(pexpect.EOF)#open完文件,利用终了后,需封闭该文件.fout.close()return0if__name__=="__main__":try:main()exceptSystemExit,e:raiseeexceptException,e:print"ERROR"printstr(e)traceback.print_exc()os._exit(1)
注:
[*]运转:./command.py-a-cwhocmd.log
运转停止后,cmd.log的内容为:IBMdeveloperWorksChinaRoot:02009-05-1222:40Rootpts/12009-05-1222:40(:0.0)Rootpts/22009-07-0518:55(9.77.180.94)
[*]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。
[*]假如挪用的函数终极都没有挪用send或read_nonblocking,那末logfile固然被分派指定了一个file,但其终极了局是:内容为空。见下例:
清单3.log内容为空的例子代码
importpexpectp=pexpect.spawn(‘ls-l’)fout=open(log.txt,"w")p.logfile=foutfout.close()
运转该剧本后,你会发明实在log.txt是空的,没有纪录ls-l下令的内容,缘故原由是没有挪用send或read_nonblocking,真实的内容没有被flush到log中。假如在fout.close()之前加上p.expect(pexpect.EOF),log.txt才会有ls-l下令的内容。
http://www.centoscn.com/uploads/allimg/130726/0050451b8-0.gif
http://www.centoscn.com/uploads/allimg/130726/005045D64-1.gif
回页首
例3:ssh的利用
本例完成了以下功效:ssh登录到某个用户指定的主机上,运转某个用户指定的下令,并输入该下令的了局。
清单4.ssh的例子代码
#!/usr/bin/envpython"""ThisrunsacommandonaremotehostusingSSH.Atthepromptsenterhostname,user,passwordandthecommand."""importpexpectimportgetpass,os#user:ssh主机的用户名#host:ssh主机的域名#password:ssh主机的暗码#command:行将在远端ssh主机上运转的下令defssh_command(user,host,password,command):"""Thisrunsacommandontheremotehost.Thiscouldalsobedonewiththepxsshclass,butthisdemonstrateswhatthatclassdoesatasimplerlevel.Thisreturnsapexpect.spawnobject.Thishandlesthecasewhenyoutrytoconnecttoanewhostandsshasksyouifyouwanttoacceptthepublickeyfingerprintandcontinueconnecting."""ssh_newkey=Areyousureyouwanttocontinueconnecting#为ssh下令天生一个spawn类的子步伐工具.child=pexpect.spawn(ssh-l%s%s%s%(user,host,command))i=child.expect()#假如登录超时,打印堕落信息,并加入.ifi==0:#TimeoutprintERROR!printSSHcouldnotlogin.HereiswhatSSHsaid:printchild.before,child.afterreturnNone#假如ssh没有publickey,承受它.ifi==1:#SSHdoesnothavethepublickey.Justacceptit.child.sendline(yes)child.expect(password:)i=child.expect()ifi==0:#TimeoutprintERROR!printSSHcouldnotlogin.HereiswhatSSHsaid:printchild.before,child.afterreturnNone#输出暗码.child.sendline(password)returnchilddefmain():#取得用户指定ssh主机域名.host=raw_input(Hostname:)#取得用户指定ssh主机用户名.user=raw_input(User:)#取得用户指定ssh主秘密码.password=getpass.getpass()#取得用户指定ssh主机上行将运转的下令.command=raw_input(Enterthecommand:)child=ssh_command(user,host,password,command)#婚配pexpect.EOFchild.expect(pexpect.EOF)#输入下令了局.printchild.beforeif__name__==__main__:try:main()exceptException,e:printstr(e)traceback.print_exc()os._exit(1)
注:
[*]运转后,输入了局为:
Hostname:develperWorks.ibm.comUser:rootPassword:Enterthecommand:ls-ltotal60drwxr-xr-x2rootsystem512Jun142006.dtdrwxrwxr-x3rootsystem512Sep232008.java-rwx------1rootsystem1855Jun142006.kshrc-rwx------1rootsystem806Sep162008.profile-rwx------1rootsystem60Jun142006.rhostsdrwx------2rootsystem512Jan182007.sshdrwxr-x---2rootsystem512Apr1500:04223002-rwxr-xr-x1rootsystem120Jan162007drcron.sh-rwx------1rootsystem10419Jun142006firewalldrwxr-x---2rootsystem512Oct252007jre-rw-------1rootsystem3203Apr042008mbox-rw-r--r--1rootsystem0Jun142006pt1-rw-r--r--1rootsystem0Jun142006pt2
[*]利用了getpass.getpass()来取得用户输出的暗码,与raw_input分歧的是,getpass.getpass()不会将用户输出的暗码字符串echo回显到stdout上。(更多python相干手艺,请参阅参考材料)
http://www.centoscn.com/uploads/allimg/130726/0050451b8-0.gif
http://www.centoscn.com/uploads/allimg/130726/005045D64-1.gif
回页首
例4:pxssh的利用
本例完成了以下功效:利用pexpect自带的pxssh模块完成ssh登录到某个用户指定的主机上,运转下令’uptime’和’ls-l’,并输入该下令的了局。
清单5.利用pxssh的例子代码
#!/usr/bin/envpythonimportpxsshimportgetpasstry:#挪用机关函数,创立一个pxssh类的工具.s=pxssh.pxssh()#取得用户指定ssh主机域名.hostname=raw_input(hostname:)#取得用户指定ssh主机用户名.username=raw_input(username:)#取得用户指定ssh主秘密码.password=getpass.getpass(password:)#使用pxssh类的login***举行ssh登录,原始prompt为$,#或>s.login(hostname,username,password,original_prompt=[$#>])#发送死令uptimes.sendline(uptime)#婚配prompts.prompt()#将prompt前一切内容打印出,即下令uptime的实行了局.prints.before#发送死令ls-ls.sendline(ls-l)#婚配prompts.prompt()#将prompt前一切内容打印出,即下令ls-l的实行了局.prints.before#加入sshsessions.logout()exceptpxssh.ExceptionPxssh,e:print"pxsshfailedonlogin."printstr(e)
[*]运转后,输入了局为:
hostname:develperWorks.ibm.comusername:rootpassword:uptime02:19AMup292days,12:16,2users,loadaverage:0.01,0.02,0.01ls-ltotal60drwxr-xr-x2rootsystem512Jun142006.dtdrwxrwxr-x3rootsystem512Sep232008.java-rwx------1rootsystem1855Jun142006.kshrc-rwx------1rootsystem806Sep162008.profile-rwx------1rootsystem60Jun142006.rhostsdrwx------2rootsystem512Jan182007.sshdrwxr-x---2rootsystem512Apr1500:04223002-rwxr-xr-x1rootsystem120Jan162007drcron.sh-rwx------1rootsystem10419Jun142006firewalldrwxr-x---2rootsystem512Oct252007jre-rw-------1rootsystem3203Apr042008mbox-rw-r--r--1rootsystem0Jun142006pt1-rw-r--r--1rootsystem0Jun142006pt2
[*]pxssh是pexpect中spawn类的子类,增添了login,logout和prompt几个***,利用其能够轻松完成ssh毗连,而不必本人挪用绝对庞大的pexpect的***来完成。pxssh做了良多tricky的器材来处置sshlogin过程当中所大概碰到的各类情形。好比:假如这个session是第一次login,pxssh会主动承受近程整数remotecertificate;假如你已设置了公钥认证,pxssh将不会再守候password的提醒符。(更多ssh相干常识,请参阅参考材料)pxssh利用shell的提醒符来同步近程主机的输入,为了使步伐加倍不乱,pxssh还能够设置prompt为加倍独一的字符串,而不单单是“$”和“#”。
[*]login***
login(self,server,username,password=,terminal_type=ansi,iginal_prompt=r"[#$]",login_timeout=10,port=None,auto_prompt_reset=True):
利用原始original_prompt来找到login后的提醒符(这里默许original_prompt是“$”或“#”,可是偶然候大概也是其余prompt,这时候就必要在login时手动指定这个特别的prompt,见上例,有多是“>”),假如找到了,立马利用更简单婚配的字符串来重置该原始提醒符(这是由pxssh本人主动做的,经由过程下令"PS1=$"重置原始提醒符,然后每次expect婚配[$#])。原始提醒符是很简单被搅浑和胡弄的,为了制止毛病婚配,最好依据特定的体系,指定加倍准确的原始提醒符,比方"MessageOfTheDay"。有些情形是不同意重置原始提醒符的,这时候就要设置auto_prompt_reset为False。并且此时必要手动设置PROMPT域为某个正则表达式来match接上去要呈现的新提醒符,由于prompt()函数默许是expect被重置过的PROMPT的。
[*]prompt***
Congratulations!ftplogincorrect!gettingafile...successfullyreceivedthefile0
婚配新提醒符(不是original_prompt)。注:这只是婚配提醒符,不克不及婚配其余string,假如要婚配特别string,需间接利用父类spawn的expect***。prompt***相称因而expect***的一个快速***。假如auto_prompt_reset为False,这时候必要手动设置PROMPT域为某个正则表达式来match接上去要呈现的prompt,由于prompt()函数默许是expect被重置过的PROMPT的。
[*]logout***
Congratulations!ftplogincorrect!gettingafile...successfullyreceivedthefile1
发送exit给近程ssh主机,假如有stoppedjobs,会发送exit两次。
http://www.centoscn.com/uploads/allimg/130726/0050451b8-0.gif
http://www.centoscn.com/uploads/allimg/130726/005045D64-1.gif
回页首
例5:telnet的利用
本例完成了以下功效:telnet登录到某近程主机上,输出下令“ls-l”后,将子步伐的实行权交还给用户,用户能够与天生的telnet子步伐举行交互。
清单6.telnet的例子代码
Congratulations!ftplogincorrect!gettingafile...successfullyreceivedthefile2
[*]运转后,输入了局为:
Congratulations!ftplogincorrect!gettingafile...successfullyreceivedthefile3
[*]interact***
Congratulations!ftplogincorrect!gettingafile...successfullyreceivedthefile4
一般一个python主步伐经由过程pexpect.spawn启动一个子步伐,一旦该子步伐启动后,python主步伐就能够经由过程child.expect和child.send/child.sendline来和子步伐通话,python主步伐运转停止后,子步伐也就逝世了。好比python主步伐经由过程pexpect.spawn启动了一个telnet子步伐,在举行完一系列的telnet上的下令操纵后,python主步伐运转停止了,那末该telnetsession(telnet子步伐)也会主动加入。可是假如挪用child.interact,那末该子步伐(python主步伐经由过程pexpect.spawn衍天生的)就能够在运转到child.interact时,将子步伐的把持权交给了终端用户(thehumanatthekeyboard),用户能够经由过程键盘的输出来和子步伐举行下令交互,办理子步伐的生杀年夜权,用户的键盘输出stdin会被传给子步伐,并且子步伐的stdout和stderr输入也会被打印出离开终端。默许ctrl+]加入interact()形式,把子步伐的实行权从头交给python主步伐。参数escape_character指定了交互形式的加入字符,比方child.interact(chr(26))接上去就会酿成ctrl+z加入interact()形式。
http://www.centoscn.com/uploads/allimg/130726/0050451b8-0.gif
http://www.centoscn.com/uploads/allimg/130726/005045D64-1.gif
回页首
pexpect利用tips
调试pexpect步伐的tips
[*]取得pexpect.spawn工具的字符串value值,将会给debug供应良多有效信息。
清单7.打印pexpect.spawn工具的字符串value值的例子代码
Congratulations!ftplogincorrect!gettingafile...successfullyreceivedthefile5
[*]将子步伐的input和output打log到文件中或者间接打log到屏幕上也十分有效
清单8.纪录log的例子代码
Congratulations!ftplogincorrect!gettingafile...successfullyreceivedthefile6
pexpect不会注释shell中的元字符
[*]pexpect不会注释shell的元字符,如重定向redirect,管道pipe,和通配符wildcards(“>”,“|”和“*”等)假如想用的话,必需得从头启动一个新shell(在spawn的参数command中是不会注释他们的,视其为commandstring的一个一般字符)
清单9.从头启动一个shell来躲避pexpect对元字符的不注释
Congratulations!ftplogincorrect!gettingafile...successfullyreceivedthefile7
假如想在spawn出来的新子步伐中利用重定向redirect,管道pipe,和通配符wildcards(“>”,“|”和“*”等),仿佛没有好的***,只能不利用这些字符,先使用expect婚配下令提醒符,从而在before中能够拿到之前下令的了局,然后在剖析before的内容到达利用重定向redirect,管道pipe,和通配符wildcards的目标。
EOF非常和TIMEOUT非常
[*]TIMEOUT非常
假如子步伐没有在指定的工夫内天生任何output,那末expect()和read()城市发生TIMEOUT非常。超时默许是30s,能够在expect()和spawn机关函数初始化时指定为别的工夫,如:
Congratulations!ftplogincorrect!gettingafile...successfullyreceivedthefile8
假如你想让expect()和read()疏忽超时限定,即无穷期堵塞住直到有output发生,设置timeout参数为None。
清单10.疏忽timeout超时限定的例子代码
Congratulations!ftplogincorrect!gettingafile...successfullyreceivedthefile9
[*]EOF非常
大概会有两种EOF非常被抛出,可是他们除显现的信息分歧,实在实质上是不异的。为了有用的目标,不必要辨别它们,他们只是给了些关于你的python步伐究竟运转在哪一个平台上的分外信息,这两个显现信息是:
#!/usr/bin/envpython"""Thisrunauserspecifiedcommandandlogitsresult../command.py[-a][-ccommand]{logfilename}logfilename:Thisisthenameofthelogfile.Defaultiscommand.log.-a:Appendtologfile.Defaultistooverwritelogfile.-c:spawncommand.Defaultisthecommandls-l.Example:Thiswillexecutethecommandpwdandappendtothelognamedmy_session.log:./command.py-a-cpwdmy_session.log"""importos,sys,getoptimporttracebackimportpexpect#假如步伐两头堕落,打印提醒信息前进出defexit_with_usage():printglobals()os._exit(1)defmain():#######################################################################Parsetheoptions,arguments,getready,etc.######################################################################try:optlist,args=getopt.getopt(sys.argv,h?ac:,)#假如指定的参数不是’-a’,‘-h’,‘-c’,‘-?’,‘--help’,#‘--h’或’--?’时,会抛出exception,#这里catch住,然后打印出exception的信息,并输入usage提醒信息.exceptException,e:printstr(e)exit_with_usage()options=dict(optlist)#最多只能指定一个logfile,不然堕落.iflen(args)>1:exit_with_usage()#假如指定的是-h,--h,-?,--?或--help,只输入usage提醒信息.if]:print"Help:"exit_with_usage()#猎取logfile的名字.iflen(args)==1:script_filename=argselse:#假如用户没指定,默许logfile的名字是command.logscript_filename="command.log"#假如用户指定了参数-a,假如之前该logfile存在,那末接上去的内容会附加在本来内容以后,#假如之前没有该logfile,新建一个文件,而且接上去将内容写进到该文件中.if-ainoptions:fout=open(script_filename,"ab")else:#假如用户没指定参数-a,默许依照用户指定logfile文件名新建一个文件,然后将接上去将内容写进到该文件中.fout=open(script_filename,"wb")#假如用户指定了-c参数,那末运转用户指定的下令.if-cinoptions:command=options[-c]#假如用户没有指定-c参数,那末默许运转下令ls–lelse:command="ls-l"#logfile文件的titlefout.write(==========LogTile:IBMdeveloperWorksChina==========
)#为接上去的运转下令天生一个pexpect的spawn类子步伐的工具.p=pexpect.spawn(command)#将之前open的file工具指定为spawn类子步伐工具的log文件.p.logfile=fout#下令运转完后,expectEOF呈现,这时候会将spawn类子步伐工具的输入写进到log文件.p.expect(pexpect.EOF)#open完文件,利用终了后,需封闭该文件.fout.close()return0if__name__=="__main__":try:main()exceptSystemExit,e:raiseeexceptException,e:print"ERROR"printstr(e)traceback.print_exc()os._exit(1)0
有些UNIX平台,当你读取一个处于EOF形态的文件形貌符时,会抛出非常,其他UNIX平台,却只会悄悄地前往一个空字符串来标明该文件已到达了形态。
利用run()来替换某些的spawn的利用
pexpect模块除供应spawn类之外,还供应了run()函数,利用其能够代替一些spawn的利用,并且加倍复杂了然。
清单11.利用run()来替换spawn的利用的例子代码
#!/usr/bin/envpython"""Thisrunauserspecifiedcommandandlogitsresult../command.py[-a][-ccommand]{logfilename}logfilename:Thisisthenameofthelogfile.Defaultiscommand.log.-a:Appendtologfile.Defaultistooverwritelogfile.-c:spawncommand.Defaultisthecommandls-l.Example:Thiswillexecutethecommandpwdandappendtothelognamedmy_session.log:./command.py-a-cpwdmy_session.log"""importos,sys,getoptimporttracebackimportpexpect#假如步伐两头堕落,打印提醒信息前进出defexit_with_usage():printglobals()os._exit(1)defmain():#######################################################################Parsetheoptions,arguments,getready,etc.######################################################################try:optlist,args=getopt.getopt(sys.argv,h?ac:,)#假如指定的参数不是’-a’,‘-h’,‘-c’,‘-?’,‘--help’,#‘--h’或’--?’时,会抛出exception,#这里catch住,然后打印出exception的信息,并输入usage提醒信息.exceptException,e:printstr(e)exit_with_usage()options=dict(optlist)#最多只能指定一个logfile,不然堕落.iflen(args)>1:exit_with_usage()#假如指定的是-h,--h,-?,--?或--help,只输入usage提醒信息.if]:print"Help:"exit_with_usage()#猎取logfile的名字.iflen(args)==1:script_filename=argselse:#假如用户没指定,默许logfile的名字是command.logscript_filename="command.log"#假如用户指定了参数-a,假如之前该logfile存在,那末接上去的内容会附加在本来内容以后,#假如之前没有该logfile,新建一个文件,而且接上去将内容写进到该文件中.if-ainoptions:fout=open(script_filename,"ab")else:#假如用户没指定参数-a,默许依照用户指定logfile文件名新建一个文件,然后将接上去将内容写进到该文件中.fout=open(script_filename,"wb")#假如用户指定了-c参数,那末运转用户指定的下令.if-cinoptions:command=options[-c]#假如用户没有指定-c参数,那末默许运转下令ls–lelse:command="ls-l"#logfile文件的titlefout.write(==========LogTile:IBMdeveloperWorksChina==========
)#为接上去的运转下令天生一个pexpect的spawn类子步伐的工具.p=pexpect.spawn(command)#将之前open的file工具指定为spawn类子步伐工具的log文件.p.logfile=fout#下令运转完后,expectEOF呈现,这时候会将spawn类子步伐工具的输入写进到log文件.p.expect(pexpect.EOF)#open完文件,利用终了后,需封闭该文件.fout.close()return0if__name__=="__main__":try:main()exceptSystemExit,e:raiseeexceptException,e:print"ERROR"printstr(e)traceback.print_exc()os._exit(1)1
[*]run(command,timeout=-1,withexitstatus=False,events=None,extra_args=None,logfile=None,cwd=None,env=None):
[*]command:实行一个下令,然后前往了局,run()能够交换os.system()(更多os.system()常识,请参阅参考材料),由于os.system()得不到下令输入的了局
[*]前往的output是个字符串,STDERR也会包含在output中,假如全路径没有被指定,那末path会被search
[*]timeout:单元s秒,每隔timeout天生一个pexpect.TIMEOUT非常
[*]每行之间被CR/LF(
)相隔,即便在Unix平台上也是CR/LF,由于Pexpect子步伐是伪tty设备
[*]withexitstatus:设置为True,则前往一个tuple,内里包含(command_output,exitstatus),假如其为False,那末只是仅仅前往command_output
[*]events:是个dictionary,内里寄存{pattern:response}。不管甚么时分pattern在下令的了局中呈现了,会呈现以下举措:
[*]发送响应的responseString。假如必要回车符“Enter”的话,“
”也必需得呈现在response字符串中。
[*]response一样也能够是个回调函数,不外该回调函数有特别请求,即它的参数必需是个dictionary,该dictionary的内容是:包括一切在run()中界说的部分变量,从而供应了***能够会见run()函数中spawn天生的子步伐和run()中界说的其他部分变量,个中event_count,child,和extra_args最有效。回调函数大概前往True,从而制止以后run()持续实行,不然run()会持续实行直到下一个event。回调函数也大概前往一个字符串,然后被发送给子步伐。extra_args不是间接被run()利用,它只是供应了一个***能够经由过程run()来将数据传进到回调函数中(实际上是经由过程run()界说的部分变量dictionary来传)
清单12.别的一些利用run()的例子代码
#!/usr/bin/envpython"""Thisrunauserspecifiedcommandandlogitsresult../command.py[-a][-ccommand]{logfilename}logfilename:Thisisthenameofthelogfile.Defaultiscommand.log.-a:Appendtologfile.Defaultistooverwritelogfile.-c:spawncommand.Defaultisthecommandls-l.Example:Thiswillexecutethecommandpwdandappendtothelognamedmy_session.log:./command.py-a-cpwdmy_session.log"""importos,sys,getoptimporttracebackimportpexpect#假如步伐两头堕落,打印提醒信息前进出defexit_with_usage():printglobals()os._exit(1)defmain():#######################################################################Parsetheoptions,arguments,getready,etc.######################################################################try:optlist,args=getopt.getopt(sys.argv,h?ac:,)#假如指定的参数不是’-a’,‘-h’,‘-c’,‘-?’,‘--help’,#‘--h’或’--?’时,会抛出exception,#这里catch住,然后打印出exception的信息,并输入usage提醒信息.exceptException,e:printstr(e)exit_with_usage()options=dict(optlist)#最多只能指定一个logfile,不然堕落.iflen(args)>1:exit_with_usage()#假如指定的是-h,--h,-?,--?或--help,只输入usage提醒信息.if]:print"Help:"exit_with_usage()#猎取logfile的名字.iflen(args)==1:script_filename=argselse:#假如用户没指定,默许logfile的名字是command.logscript_filename="command.log"#假如用户指定了参数-a,假如之前该logfile存在,那末接上去的内容会附加在本来内容以后,#假如之前没有该logfile,新建一个文件,而且接上去将内容写进到该文件中.if-ainoptions:fout=open(script_filename,"ab")else:#假如用户没指定参数-a,默许依照用户指定logfile文件名新建一个文件,然后将接上去将内容写进到该文件中.fout=open(script_filename,"wb")#假如用户指定了-c参数,那末运转用户指定的下令.if-cinoptions:command=options[-c]#假如用户没有指定-c参数,那末默许运转下令ls–lelse:command="ls-l"#logfile文件的titlefout.write(==========LogTile:IBMdeveloperWorksChina==========
)#为接上去的运转下令天生一个pexpect的spawn类子步伐的工具.p=pexpect.spawn(command)#将之前open的file工具指定为spawn类子步伐工具的log文件.p.logfile=fout#下令运转完后,expectEOF呈现,这时候会将spawn类子步伐工具的输入写进到log文件.p.expect(pexpect.EOF)#open完文件,利用终了后,需封闭该文件.fout.close()return0if__name__=="__main__":try:main()exceptSystemExit,e:raiseeexceptException,e:print"ERROR"printstr(e)traceback.print_exc()os._exit(1)2
expect_exact()的利用
expect_exact(self,pattern_list,timeout=-1,searchwindowsize=-1);expect_exact()与expect()相似,可是pattern_list只能是字符串大概是一个字符串的list,不克不及是正则表达式,其婚配速率会快于expect(),缘故原由有两个:一是字符串的search比正则表达式的婚配要快,另外一个则是能够限定只从输出缓冲的开头来寻觅婚配的字符串。另有当你以为每主要escape正则表达式中的特别字符为一般字符时很烦,那末你也能够利用expect_exact()来代替expect()。
清单13.expect_exact()的例子代码
#!/usr/bin/envpython"""Thisrunauserspecifiedcommandandlogitsresult../command.py[-a][-ccommand]{logfilename}logfilename:Thisisthenameofthelogfile.Defaultiscommand.log.-a:Appendtologfile.Defaultistooverwritelogfile.-c:spawncommand.Defaultisthecommandls-l.Example:Thiswillexecutethecommandpwdandappendtothelognamedmy_session.log:./command.py-a-cpwdmy_session.log"""importos,sys,getoptimporttracebackimportpexpect#假如步伐两头堕落,打印提醒信息前进出defexit_with_usage():printglobals()os._exit(1)defmain():#######################################################################Parsetheoptions,arguments,getready,etc.######################################################################try:optlist,args=getopt.getopt(sys.argv,h?ac:,)#假如指定的参数不是’-a’,‘-h’,‘-c’,‘-?’,‘--help’,#‘--h’或’--?’时,会抛出exception,#这里catch住,然后打印出exception的信息,并输入usage提醒信息.exceptException,e:printstr(e)exit_with_usage()options=dict(optlist)#最多只能指定一个logfile,不然堕落.iflen(args)>1:exit_with_usage()#假如指定的是-h,--h,-?,--?或--help,只输入usage提醒信息.if]:print"Help:"exit_with_usage()#猎取logfile的名字.iflen(args)==1:script_filename=argselse:#假如用户没指定,默许logfile的名字是command.logscript_filename="command.log"#假如用户指定了参数-a,假如之前该logfile存在,那末接上去的内容会附加在本来内容以后,#假如之前没有该logfile,新建一个文件,而且接上去将内容写进到该文件中.if-ainoptions:fout=open(script_filename,"ab")else:#假如用户没指定参数-a,默许依照用户指定logfile文件名新建一个文件,然后将接上去将内容写进到该文件中.fout=open(script_filename,"wb")#假如用户指定了-c参数,那末运转用户指定的下令.if-cinoptions:command=options[-c]#假如用户没有指定-c参数,那末默许运转下令ls–lelse:command="ls-l"#logfile文件的titlefout.write(==========LogTile:IBMdeveloperWorksChina==========
)#为接上去的运转下令天生一个pexpect的spawn类子步伐的工具.p=pexpect.spawn(command)#将之前open的file工具指定为spawn类子步伐工具的log文件.p.logfile=fout#下令运转完后,expectEOF呈现,这时候会将spawn类子步伐工具的输入写进到log文件.p.expect(pexpect.EOF)#open完文件,利用终了后,需封闭该文件.fout.close()return0if__name__=="__main__":try:main()exceptSystemExit,e:raiseeexceptException,e:print"ERROR"printstr(e)traceback.print_exc()os._exit(1)3
expect()中正则表达式的利用tips
expect()中的正则表达式不是贪心婚配greedymatch,而是最小婚配,即只婚配缓冲区中最早呈现的第一个字符串。由于是顺次读取一个字符的stream流来判别是不是和正则表达式所表达的形式婚配,以是假如参数pattern是个list,并且不止一次婚配,那末缓冲区中最早呈现的第一个婚配的字符串才算数。
清单14.expect()的最小婚配例子代码
#!/usr/bin/envpython"""Thisrunauserspecifiedcommandandlogitsresult../command.py[-a][-ccommand]{logfilename}logfilename:Thisisthenameofthelogfile.Defaultiscommand.log.-a:Appendtologfile.Defaultistooverwritelogfile.-c:spawncommand.Defaultisthecommandls-l.Example:Thiswillexecutethecommandpwdandappendtothelognamedmy_session.log:./command.py-a-cpwdmy_session.log"""importos,sys,getoptimporttracebackimportpexpect#假如步伐两头堕落,打印提醒信息前进出defexit_with_usage():printglobals()os._exit(1)defmain():#######################################################################Parsetheoptions,arguments,getready,etc.######################################################################try:optlist,args=getopt.getopt(sys.argv,h?ac:,)#假如指定的参数不是’-a’,‘-h’,‘-c’,‘-?’,‘--help’,#‘--h’或’--?’时,会抛出exception,#这里catch住,然后打印出exception的信息,并输入usage提醒信息.exceptException,e:printstr(e)exit_with_usage()options=dict(optlist)#最多只能指定一个logfile,不然堕落.iflen(args)>1:exit_with_usage()#假如指定的是-h,--h,-?,--?或--help,只输入usage提醒信息.if]:print"Help:"exit_with_usage()#猎取logfile的名字.iflen(args)==1:script_filename=argselse:#假如用户没指定,默许logfile的名字是command.logscript_filename="command.log"#假如用户指定了参数-a,假如之前该logfile存在,那末接上去的内容会附加在本来内容以后,#假如之前没有该logfile,新建一个文件,而且接上去将内容写进到该文件中.if-ainoptions:fout=open(script_filename,"ab")else:#假如用户没指定参数-a,默许依照用户指定logfile文件名新建一个文件,然后将接上去将内容写进到该文件中.fout=open(script_filename,"wb")#假如用户指定了-c参数,那末运转用户指定的下令.if-cinoptions:command=options[-c]#假如用户没有指定-c参数,那末默许运转下令ls–lelse:command="ls-l"#logfile文件的titlefout.write(==========LogTile:IBMdeveloperWorksChina==========
)#为接上去的运转下令天生一个pexpect的spawn类子步伐的工具.p=pexpect.spawn(command)#将之前open的file工具指定为spawn类子步伐工具的log文件.p.logfile=fout#下令运转完后,expectEOF呈现,这时候会将spawn类子步伐工具的输入写进到log文件.p.expect(pexpect.EOF)#open完文件,利用终了后,需封闭该文件.fout.close()return0if__name__=="__main__":try:main()exceptSystemExit,e:raiseeexceptException,e:print"ERROR"printstr(e)traceback.print_exc()os._exit(1)4
[*]“$”不起任何感化,婚配一行的停止(endofline),必需得婚配CR/LF
正则表达式中,$能够婚配一行的停止(详细$正则表达式的利用,请参阅参考材料),可是pexpect从子步伐中一次只读取一个字符,并且每一个字符都仿佛是一行的停止一样,pexpect不克不及在子步伐的输入流往展望。婚配一行停止的***必需是婚配"
"(CR/LF)。即便是Unix体系,也是婚配"
"(CR/LF),由于pexpect利用一个Pseudo-TTY设备与子步伐通话,以是当子步伐输入"
"你仍旧会在python主步伐中看到"
"。缘故原由是TTY设备更像windows操纵体系,每行停止都有个"
"(CR/LF)的组合,当你从TTY设备往注释一个Unix的下令时,你会发明真实的输入是"
"(CR/LF),一个Unix下令只会写进一个linefeed(
),可是TTY设备驱动会将其转换成"
"(CR/LF)。
清单15.婚配一行停止1
#!/usr/bin/envpython"""Thisrunauserspecifiedcommandandlogitsresult../command.py[-a][-ccommand]{logfilename}logfilename:Thisisthenameofthelogfile.Defaultiscommand.log.-a:Appendtologfile.Defaultistooverwritelogfile.-c:spawncommand.Defaultisthecommandls-l.Example:Thiswillexecutethecommandpwdandappendtothelognamedmy_session.log:./command.py-a-cpwdmy_session.log"""importos,sys,getoptimporttracebackimportpexpect#假如步伐两头堕落,打印提醒信息前进出defexit_with_usage():printglobals()os._exit(1)defmain():#######################################################################Parsetheoptions,arguments,getready,etc.######################################################################try:optlist,args=getopt.getopt(sys.argv,h?ac:,)#假如指定的参数不是’-a’,‘-h’,‘-c’,‘-?’,‘--help’,#‘--h’或’--?’时,会抛出exception,#这里catch住,然后打印出exception的信息,并输入usage提醒信息.exceptException,e:printstr(e)exit_with_usage()options=dict(optlist)#最多只能指定一个logfile,不然堕落.iflen(args)>1:exit_with_usage()#假如指定的是-h,--h,-?,--?或--help,只输入usage提醒信息.if]:print"Help:"exit_with_usage()#猎取logfile的名字.iflen(args)==1:script_filename=argselse:#假如用户没指定,默许logfile的名字是command.logscript_filename="command.log"#假如用户指定了参数-a,假如之前该logfile存在,那末接上去的内容会附加在本来内容以后,#假如之前没有该logfile,新建一个文件,而且接上去将内容写进到该文件中.if-ainoptions:fout=open(script_filename,"ab")else:#假如用户没指定参数-a,默许依照用户指定logfile文件名新建一个文件,然后将接上去将内容写进到该文件中.fout=open(script_filename,"wb")#假如用户指定了-c参数,那末运转用户指定的下令.if-cinoptions:command=options[-c]#假如用户没有指定-c参数,那末默许运转下令ls–lelse:command="ls-l"#logfile文件的titlefout.write(==========LogTile:IBMdeveloperWorksChina==========
)#为接上去的运转下令天生一个pexpect的spawn类子步伐的工具.p=pexpect.spawn(command)#将之前open的file工具指定为spawn类子步伐工具的log文件.p.logfile=fout#下令运转完后,expectEOF呈现,这时候会将spawn类子步伐工具的输入写进到log文件.p.expect(pexpect.EOF)#open完文件,利用终了后,需封闭该文件.fout.close()return0if__name__=="__main__":try:main()exceptSystemExit,e:raiseeexceptException,e:print"ERROR"printstr(e)traceback.print_exc()os._exit(1)5
假如你只是想跳过一个新行,间接expect(
)就能够了,可是假如你想在一行的停止婚配一个详细的pattern时,就必需准确的寻觅(),见下例:
清单16.婚配一行停止2
#!/usr/bin/envpython"""Thisrunauserspecifiedcommandandlogitsresult../command.py[-a][-ccommand]{logfilename}logfilename:Thisisthenameofthelogfile.Defaultiscommand.log.-a:Appendtologfile.Defaultistooverwritelogfile.-c:spawncommand.Defaultisthecommandls-l.Example:Thiswillexecutethecommandpwdandappendtothelognamedmy_session.log:./command.py-a-cpwdmy_session.log"""importos,sys,getoptimporttracebackimportpexpect#假如步伐两头堕落,打印提醒信息前进出defexit_with_usage():printglobals()os._exit(1)defmain():#######################################################################Parsetheoptions,arguments,getready,etc.######################################################################try:optlist,args=getopt.getopt(sys.argv,h?ac:,)#假如指定的参数不是’-a’,‘-h’,‘-c’,‘-?’,‘--help’,#‘--h’或’--?’时,会抛出exception,#这里catch住,然后打印出exception的信息,并输入usage提醒信息.exceptException,e:printstr(e)exit_with_usage()options=dict(optlist)#最多只能指定一个logfile,不然堕落.iflen(args)>1:exit_with_usage()#假如指定的是-h,--h,-?,--?或--help,只输入usage提醒信息.if]:print"Help:"exit_with_usage()#猎取logfile的名字.iflen(args)==1:script_filename=argselse:#假如用户没指定,默许logfile的名字是command.logscript_filename="command.log"#假如用户指定了参数-a,假如之前该logfile存在,那末接上去的内容会附加在本来内容以后,#假如之前没有该logfile,新建一个文件,而且接上去将内容写进到该文件中.if-ainoptions:fout=open(script_filename,"ab")else:#假如用户没指定参数-a,默许依照用户指定logfile文件名新建一个文件,然后将接上去将内容写进到该文件中.fout=open(script_filename,"wb")#假如用户指定了-c参数,那末运转用户指定的下令.if-cinoptions:command=options[-c]#假如用户没有指定-c参数,那末默许运转下令ls–lelse:command="ls-l"#logfile文件的titlefout.write(==========LogTile:IBMdeveloperWorksChina==========
)#为接上去的运转下令天生一个pexpect的spawn类子步伐的工具.p=pexpect.spawn(command)#将之前open的file工具指定为spawn类子步伐工具的log文件.p.logfile=fout#下令运转完后,expectEOF呈现,这时候会将spawn类子步伐工具的输入写进到log文件.p.expect(pexpect.EOF)#open完文件,利用终了后,需封闭该文件.fout.close()return0if__name__=="__main__":try:main()exceptSystemExit,e:raiseeexceptException,e:print"ERROR"printstr(e)traceback.print_exc()os._exit(1)6
这个成绩实在不但是pexpect会有,假如你在一个stream流上实行正则表达式婚配时,城市碰到此成绩。正则表达式必要展望,stream流中很难展望,由于天生这个流的历程大概还没有停止,以是你很难晓得是不是该历程是临时性的停息仍是已完全停止。
[*]当.和*呈现在最初时
child.expect(.+);由于是最小婚配,以是只会前往一个字符,而不是一个全部一行(固然pexpect设置了re.DOTALL,会婚配一个新行。child.expect(.*);每次婚配城市乐成,可是老是没有字符前往,由于*标明后面的字符能够呈现0次,在pexpect中,一样平常来讲,任何*城市只管少的婚配。
isalive()的利用tips
[*]isalive(self)
测试子步伐是不是还在运转。这个***长短堵塞的,假如子步伐被停止了,那末该***会往读取子步伐的exitstatus或signalstatus这两个域。前往True标明子步伐仿佛是在运转,前往False暗示不再运转。当平台是Solaris时,大概必要几秒钟才干失掉准确的形态。当子步伐加入后立马实行isalive()偶然大概会前往1(True),这是一个racecondition,缘故原由是子步伐已封闭了其文件形貌符,可是在isalive()实行前还没有完整的加入。增添一个小小的延时会对isalive()的了局无效性有匡助。
清单17.isalive()的例子代码
#!/usr/bin/envpython"""Thisrunauserspecifiedcommandandlogitsresult../command.py[-a][-ccommand]{logfilename}logfilename:Thisisthenameofthelogfile.Defaultiscommand.log.-a:Appendtologfile.Defaultistooverwritelogfile.-c:spawncommand.Defaultisthecommandls-l.Example:Thiswillexecutethecommandpwdandappendtothelognamedmy_session.log:./command.py-a-cpwdmy_session.log"""importos,sys,getoptimporttracebackimportpexpect#假如步伐两头堕落,打印提醒信息前进出defexit_with_usage():printglobals()os._exit(1)defmain():#######################################################################Parsetheoptions,arguments,getready,etc.######################################################################try:optlist,args=getopt.getopt(sys.argv,h?ac:,)#假如指定的参数不是’-a’,‘-h’,‘-c’,‘-?’,‘--help’,#‘--h’或’--?’时,会抛出exception,#这里catch住,然后打印出exception的信息,并输入usage提醒信息.exceptException,e:printstr(e)exit_with_usage()options=dict(optlist)#最多只能指定一个logfile,不然堕落.iflen(args)>1:exit_with_usage()#假如指定的是-h,--h,-?,--?或--help,只输入usage提醒信息.if]:print"Help:"exit_with_usage()#猎取logfile的名字.iflen(args)==1:script_filename=argselse:#假如用户没指定,默许logfile的名字是command.logscript_filename="command.log"#假如用户指定了参数-a,假如之前该logfile存在,那末接上去的内容会附加在本来内容以后,#假如之前没有该logfile,新建一个文件,而且接上去将内容写进到该文件中.if-ainoptions:fout=open(script_filename,"ab")else:#假如用户没指定参数-a,默许依照用户指定logfile文件名新建一个文件,然后将接上去将内容写进到该文件中.fout=open(script_filename,"wb")#假如用户指定了-c参数,那末运转用户指定的下令.if-cinoptions:command=options[-c]#假如用户没有指定-c参数,那末默许运转下令ls–lelse:command="ls-l"#logfile文件的titlefout.write(==========LogTile:IBMdeveloperWorksChina==========
)#为接上去的运转下令天生一个pexpect的spawn类子步伐的工具.p=pexpect.spawn(command)#将之前open的file工具指定为spawn类子步伐工具的log文件.p.logfile=fout#下令运转完后,expectEOF呈现,这时候会将spawn类子步伐工具的输入写进到log文件.p.expect(pexpect.EOF)#open完文件,利用终了后,需封闭该文件.fout.close()return0if__name__=="__main__":try:main()exceptSystemExit,e:raiseeexceptException,e:print"ERROR"printstr(e)traceback.print_exc()os._exit(1)7
delaybeforesend的利用tips
spawn类的域delaybeforesend能够匡助克制一些乖僻的举动。好比,典范的是,当一个用户利用expect()等候"Password:"提醒符时,假如婚配,立马sendline()发送暗码给子步伐,可是这个用户会看到他们的暗码被echoback回显返来了。这是由于,一般很多使用步伐城市在打印出"Password:"提醒符后,立马关失落stdin的echo,可是假如你发送暗码过快,在步伐关失落stdin的echo之前就发送暗码进来了,那末该暗码就会被echo出来。
清单18.delaybeforesend的例子代码
#!/usr/bin/envpython"""Thisrunauserspecifiedcommandandlogitsresult../command.py[-a][-ccommand]{logfilename}logfilename:Thisisthenameofthelogfile.Defaultiscommand.log.-a:Appendtologfile.Defaultistooverwritelogfile.-c:spawncommand.Defaultisthecommandls-l.Example:Thiswillexecutethecommandpwdandappendtothelognamedmy_session.log:./command.py-a-cpwdmy_session.log"""importos,sys,getoptimporttracebackimportpexpect#假如步伐两头堕落,打印提醒信息前进出defexit_with_usage():printglobals()os._exit(1)defmain():#######################################################################Parsetheoptions,arguments,getready,etc.######################################################################try:optlist,args=getopt.getopt(sys.argv,h?ac:,)#假如指定的参数不是’-a’,‘-h’,‘-c’,‘-?’,‘--help’,#‘--h’或’--?’时,会抛出exception,#这里catch住,然后打印出exception的信息,并输入usage提醒信息.exceptException,e:printstr(e)exit_with_usage()options=dict(optlist)#最多只能指定一个logfile,不然堕落.iflen(args)>1:exit_with_usage()#假如指定的是-h,--h,-?,--?或--help,只输入usage提醒信息.if]:print"Help:"exit_with_usage()#猎取logfile的名字.iflen(args)==1:script_filename=argselse:#假如用户没指定,默许logfile的名字是command.logscript_filename="command.log"#假如用户指定了参数-a,假如之前该logfile存在,那末接上去的内容会附加在本来内容以后,#假如之前没有该logfile,新建一个文件,而且接上去将内容写进到该文件中.if-ainoptions:fout=open(script_filename,"ab")else:#假如用户没指定参数-a,默许依照用户指定logfile文件名新建一个文件,然后将接上去将内容写进到该文件中.fout=open(script_filename,"wb")#假如用户指定了-c参数,那末运转用户指定的下令.if-cinoptions:command=options[-c]#假如用户没有指定-c参数,那末默许运转下令ls–lelse:command="ls-l"#logfile文件的titlefout.write(==========LogTile:IBMdeveloperWorksChina==========
)#为接上去的运转下令天生一个pexpect的spawn类子步伐的工具.p=pexpect.spawn(command)#将之前open的file工具指定为spawn类子步伐工具的log文件.p.logfile=fout#下令运转完后,expectEOF呈现,这时候会将spawn类子步伐工具的输入写进到log文件.p.expect(pexpect.EOF)#open完文件,利用终了后,需封闭该文件.fout.close()return0if__name__=="__main__":try:main()exceptSystemExit,e:raiseeexceptException,e:print"ERROR"printstr(e)traceback.print_exc()os._exit(1)8
小知识:社区支持的免费Linux发行版一般不会从商业支持中寻求什么好处,但对CentOS来说,这种情况即将改变。 可以说自己收获很大,基本上完成了老师布置的任务,对于拔高的题目没有去做,因为我了解我的水平,没有时间和精力去做。? linux鸟哥的私房菜,第三版,基础篇,网上有pdf下的,看它的目录和每章的介绍就行了,这个绝对原创! 一定要养成在命令行下工作的习惯,要知道X-window只是运行在命令行模式下的一个应用程序。在命令行下学习虽然一开始进度较慢。 如果你想深入学习Linux,看不懂因为文档实在是太难了。写的最好的、最全面的文档都是英语写的,最先发布的技术信息也都是用英语写的。 随着Linux技术的更加成熟、完善,其应用领域和市场份额继续快速增大。目前,其主要应用领域是服务器系统和嵌入式系统。然而,它的足迹已遍布各个行业,几乎无处不在。 为什么要学Linux呢?每个人都有不同的看法,下面我说说自己的感想吧。? 熟读写基础知识,学得会不如学得牢。 选择一些适于初学者的Linux社区。 Windows有MS-DOS?方式,在该方式下通过输入DOS命令来操作电脑;Linux与Windows类似,也有命令方式,Linux?启动后如果不执行?X-WINDOWS,就会处于命令方式下,必须发命令才能操作电脑。?
页:
[1]