2015-06-09 66 views
2

Backstory:我對Python很新,但是在Perl方面經驗豐富。我正試圖在我的系統管理員活動領域多樣化我的腳本組合。從外部程序中交互式地寫/讀

我試圖從我的python腳本與外部進程動態通信。

我想要做的是:

  • 調用的可執行文件(可以稱之爲「CLI」)
  • 寫一行cli來
  • 通過讀取響應回內部
  • 迭代響應,並將另一行寫入CLI
  • 將來自cli的響應打印回控制檯

什麼我希望這將產生是:

(spawn process) /usr/local/bin/cli 
-> show listofobjects 
<- (read back list of objects internally) 
-> (one by one, write a line to the cli for each of the list of objects) 
-> get objectname modifiedtime 
<- (print response from above command) 

這裏是我到目前爲止的代碼:

import shlex, subprocess, re 

clicmd = "/usr/local/bin/cli -s 10.1.213.226 -n Administrator -p password" 
cliargs = shlex.split(clicmd) 
cliproc = subprocess.Popen(cliargs, 
         stdin=subprocess.PIPE, 
         stdout=subprocess.PIPE, 
         stderr=subprocess.PIPE, 
        ) 

tmpclicmd = "LIST objects OUTPUT csv NAME" 
cliret = cliproc.communicate(input=tmpclicmd)[0] 
regex = re.compile('^\".*') 

for line in cliret.split('\n'): 
    if regex.match(line): 
     procline = line.replace('"','') 
     if 'NAME' not in procline: 
      clideets = subprocess.Popen(cliargs, 
             stdin=subprocess.PIPE, 
             stdout=subprocess.PIPE, 
             stderr=subprocess.PIPE, 
             ) 
      clideetscmd = 'modify objects ' + procline 
      clideets.communicate(input=clideetscmd) 
      clideetscmd = 'list objectdetails' 
      clideetsresp = clideets.communicate(input=clideetscmd)[0] 

      print clideetsresp; 

我可能在完全錯誤的方式去了解這一點。我需要爲這一路上的每一步產生新的Popen嗎?我怎麼能做得更好? (另一個模塊等)。在一天結束的時候,我無法接近我,Popen似乎在每一步之後都會這樣做。

在此先感謝!

+0

還有......什麼是你的問題? – TessellatingHeckler

+0

你的代碼是否工作?不行?產生錯誤?掛? – larsks

+0

一般「Pythonic」調整:交換'如果regex.match(line)不是None:'for'如果regex.match(line):'和swap'procline = line.replace(「\」「,」「)'對於'procline = line.replace('「','')'和swap'如果re.match('NAME',procline)爲None:'for'if'NAME'not in procline:' – TessellatingHeckler

回答

3
  1. 對於每次交互,沒有必要啓動一個新進程(使用Popen)。但是,如果使用communicate向該進程發送數據,則會這樣做,因爲正如文檔所述:

    與進程進行交互:將數據發送到標準輸入。從stdout和 stderr中讀取數據,直到達到文件結束。 等待進程終止。

    相反,只需寫cliproc.stdincliproc.stdout閱讀:

    cliproc.stdin.write("LIST objects OUTPUT csv NAME") 
    cliret = cliproc.stdout.readline() 
    

    的過程保持活着這樣。

  2. 我不知道爲什麼你使用shlex模塊的位置:

    clicmd = "/usr/local/bin/cli -s 10.1.213.226 -n Administrator -p password" 
    cliargs = shlex.split(clicmd) 
    

    內置str.split方法細做:

    clicmd = "/usr/local/bin/cli -s 10.1.213.226 -n Administrator -p password" 
    cliargs = clicmd.split() 
    

    或者你可以自己寫出結果列表:

    cliargs = ["/usr/local/bin/cli", "-s", "10.1.213.226", 
          "-n", "Administrator", "-p", "password"] 
    
  3. 你並不需要在這裏分號:

    print clideetsresp; 
    
+0

'cliproc.stdout.read()'也會等到文件結束。這些管道無法通過微軟區分消息​​部分。您可以使用'readline()'而不是'read()'來逐行獲取數據。 – hajtos

+0

是的。我知道有*某事*不完全正確。 – mkrieger1

+1

可能還需要編寫一個額外的'\ n'(或'print'而不是'write')和'flush()'。 – mkrieger1