2012-05-03 81 views
1

我需要使用python腳本/自動化交互式終端客戶端。客戶端接受三個參數和運行過程如下:Python中的腳本和交互式終端客戶端

>./myclient <arg1> <arg2> <arg3> 
Welcome... 
blah... 
blah.. 
[user input] 
some more blah... blah... for the input entered 
blah.. 
blah.. 
[basically it accepts input and puts the output in the console until the user types 'quit'] 

現在我需要在Python和保存在一個文件中的控制檯輸出自動執行此。

任何幫助高度讚賞...

+0

我試過Popen,但無法有效地運行終端客戶端。我也無法使用communic()發送多個輸入。當我使用stdin = PIPE,然後使用stdin.read發送數據時,客戶端很怪異 – confused1

回答

6

您可能需要使用pexpect(這是古老的期待純Python版本)。

import pexpect 
proc = pexpect.spawn('./myclient <arg1> <arg2> <arg3>') 
proc.logfile = the_logfile_you_want_to_use 
proc.expect(['the string that tells you that myclient is waiting for input']) 
proc.sendline('line you want to send to myclient') 
proc.expect(['another line you want to wait for']) 
proc.sendline('quit') # for myclient to quit 
proc.expect([pexpect.EOF]) 

像這樣的東西應該足以解決你的情況。儘管pexpect能夠做得更多,所以請閱讀文檔中的更高級用例。

+0

謝謝。這就像魅力一樣。但現在我有另一個問題。我發送兩個輸入到客戶端 'proc.sendline('input1') time.sleep(60) proc.sendline('input2')' 但問題是它不會等待。它似乎發送輸入不考慮thread.sleep(60).. – confused1

+0

通常最好不要在發送數據之前嘗試休眠,而是尋找來自其他進程的某種確認消息。 – dnaq

5

你可以看看http://docs.python.org/library/cmd.html

示例代碼:

import cmd 
import sys 

class Prompt(cmd.Cmd): 
    def __init__(self, stufflist=[]): 
     cmd.Cmd.__init__(self) 
     self.prompt = '>>> ' 
     self.stufflist = stufflist 
     print "Hello, I am your new commandline prompt! 'help' yourself!" 

    def do_quit(self, arg): 
     sys.exit(0) 

    def do_print_stuff(self, arg): 
     for s in self.stufflist: 
      print s 

p = Prompt(sys.argv[1:]) 
p.cmdloop() 

試驗例:

$ python cmdtest.py foo bar 
Hello, I am your new commandline prompt! 'help' yourself! 
>>> help 

Undocumented commands: 
====================== 
help print_stuff quit 

>>> print_stuff 
foo 
bar 
>>> quit 

爲了輸出保存到一個文件,你可以寫的東西通常會也到標準輸出到文件使用例如這個類:

class Tee(object): 
    def __init__(self, out1, out2): 
     self.out1 = out1 
     self.out2 = out2 

    def write(self, s): 
     self.out1.write(s) 
     self.out2.write(s) 

    def flush(self): 
     self.out1.flush() 
     self.out2.flush() 

您可以使用它像這樣:

with open('cmdtest.out', 'w') as f: 
    # write stdout to file and stdout 
    t = Tee(f, sys.stdout) 
    sys.stdout = t 

的一個問題是,通過命令標準輸入讀取中不會出現在這個輸出,但我相信這是可以迎刃而解。

+0

看起來我的回答是錯誤的。我錯過了什麼? :) –

+0

非常不好的人去減票。雖然它可能不是這個問題的最佳解決方案,但它是一個非常有用的答案,它顯示瞭解決這個問題的其他方法(所以我再次投票決定爲零)。 –

+0

@ Jan-PhilipGehrcke只是因爲有人提出問題並接受答案,並不意味着其他答案不正確。 :)我也發現你的答案是相當豐富的。 – SunSparc