2014-01-13 38 views
6

我使用Paramiko發出大量命令並收集結果以供進一步分析。每隔一段時間,第一個命令的結果便會完全返回,並最終返回到第二個命令的輸出中。Paramiko:如何確保在命令之間接收數據

我試圖使用recv_ready來解決這個問題,但它不工作,所以我認爲我做錯了什麼。以下是相關代碼:

pause = 1 

def issue_command(chan, pause, cmd): 
    # send commands and return results 
    chan.send(cmd + '\n') 
    while not chan.recv_ready(): 
     time.sleep(pause) 
    data = chan.recv(99999) 

ssh = paramiko.SSHClient() 
ssh.load_system_host_keys() 
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
chan = ssh.connect(host, port=22, username=username, password=password, timeout=3,) 

resp1 = issue_command(chan, pause, cmd1) 
resp2 = issue_command(chan, pause, cmd2) 

這些命令的輸出相對較小(幾句話)。增加暫停可能會解決問題,但不是一個理想的解決方案。

任何意見或建議,將不勝感激。

回答

8

我會直接使用transport併爲每個命令創建一個新的通道。然後,你可以使用類似:

def issue_command(transport, pause, command): 
    chan = transport.open_session() 
    chan.exec_command(command) 

    buff_size = 1024 
    stdout = "" 
    stderr = "" 

    while not chan.exit_status_ready(): 
     time.sleep(pause) 
     if chan.recv_ready(): 
      stdout += chan.recv(buff_size) 

     if chan.recv_stderr_ready(): 
      stderr += chan.recv_stderr(buff_size) 

    exit_status = chan.recv_exit_status() 
    # Need to gobble up any remaining output after program terminates... 
    while chan.recv_ready(): 
     stdout += chan.recv(buff_size) 

    while chan.recv_stderr_ready(): 
     stderr += chan.recv_stderr(buff_size) 

    return exit_status, stdout, stderr 

ssh = paramiko.SSHClient() 
ssh.load_system_host_keys() 
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
ssh.connect(host, port=22, username=username, password=password, timeout=3,) 
transport = ssh.get_transport() 
pause = 1  

resp1 = issue_command(transport, pause, cmd1) 
resp2 = issue_command(transport, pause, cmd2) 

一個更好的方法是採取命令列表和產卵的每個新的通道,輪詢各議員的recv_ready,並吸取他們的標準輸出/標準錯誤時,輸出可。 :-)

編輯:在命令退出後,讀取數據時可能會出現問題。請參閱評論!

+0

我覺得這讓我走上了正軌。 – KMS

+0

我覺得這讓我走上了正軌。謝謝。 我需要爲每個發出的命令創建一個新的連接和傳輸,所以我將ssh.connect和transport語句移到了issue_command函數中。迄今爲止,結果一直很好。 – KMS

+2

請注意,此解決方案可以工作,但不是防彈的 - 它可以在收到所有數據之前退出,因爲在通道流關閉之前,recv_ready()可以返回False。更多詳細信息:http://stackoverflow.com/a/39019370/2075565 – Ivan

相關問題