2013-07-19 39 views
0

我一直在使用我的腳本的unix服務器,它的工作完美。但是,當我使用相同的腳本(通過一些較小的命令更改)連接到HP Procurve交換機時,腳本崩潰並出現錯誤。該腳本的一部分是低於:paramiko ssh客戶端不能與惠普交換機一起工作

ssh = paramiko.SSHClient() 
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
ssh.connect(address, username=userna, password=passwd) 

stdin,stdout,stderr= ssh.exec_command("show ver") 

for line in stdout: 
    print '... ' + line.strip('\n') 

ssh.close() 

這給了錯誤

Traceback (most recent call last): 
File "C:/Users/kucar/Desktop/my_python/switchmodel", line 34, in <module> 
stdin,stdout,stderr= ssh.exec_command("show ver") 
File "C:\Python27\lib\site-packages\paramiko\client.py", line 379, in exec_command 
chan.exec_command(command) 
File "C:\Python27\lib\site-packages\paramiko\channel.py", line 218, in exec_command 
self._wait_for_event() 
File "C:\Python27\lib\site-packages\paramiko\channel.py", line 1122, in _wait_for_event 
raise e 
SSHException: Channel closed. 

我發現類似投訴在網上卻好像完全不提供解決方案。開關打開ssh並且用膩子工作正常。感謝您提供任何可以幫助我的想法。我無法爲100個開關手動執行「show ver」命令。

回答

1

我有連接到我的三星s4手機與ssh服務器相同的經驗。 我沒有問題連接到SUSE虛擬機或Rasperry Pi,也嘗試過MobaXterm(膩子是SO上週)。

我還沒有找到答案,但將分享我的研究。

我看了一下channel.py中的源代碼和找到的第1122行(複製如下)。

使用我的手機(可能還有您的HP開關),我注意到根本沒有登錄消息或MOTD,退出時(使用putty/mobaXterm)會話沒有正常結束。

在其他一些閱讀中,我發現parameko沒有得到作者的支持,但其他人正在努力將其移植到python 3x。

這是我找到的源代碼。

def _wait_for_send_window(self, size): 
    """ 
    (You are already holding the lock.) 
    Wait for the send window to open up, and allocate up to C{size} bytes 
    for transmission. If no space opens up before the timeout, a timeout 
    exception is raised. Returns the number of bytes available to send 
    (may be less than requested). 
    """ 
    # you are already holding the lock 
    if self.closed or self.eof_sent: 
     return 0 
    if self.out_window_size == 0: 
     # should we block? 
     if self.timeout == 0.0: 
      raise socket.timeout() 
     # loop here in case we get woken up but a different thread has filled the buffer 
     timeout = self.timeout 
     while self.out_window_size == 0: 
      if self.closed or self.eof_sent: 
       return 0 
      then = time.time() 
      self.out_buffer_cv.wait(timeout) 
      if timeout != None: 
       timeout -= time.time() - then 
       if timeout <= 0.0: 
        raise socket.timeout() 
    # we have some window to squeeze into 
1

看來,如果你不清理連結緩衝的paramiko與HP Procurves工作時去堅果。首先你需要調用一個shell,否則Paramiko會在第一個命令(正常行爲,但令人困惑)後簡單地刪除連接。

ssh = paramiko.SSHClient() 
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
ssh.connect(switch_ip, username=switch_user, password=switch_pass,look_for_keys=False) 
conn = ssh.invoke_shell() 
recieveData() # <-- see below 

實際處理數據是很重要的,正如我所學到你需要確保的paramiko實際接收到所有的數據,你問它做的東西與它之前。我通過使用以下功能來做到這一點。您可以根據需要調整睡眠,在某些情況下,0.050可以正常工作。

def recieveData(): 
    tCheck = 0 
    while not conn.recv_ready(): 
     time.sleep(1) 
     tCheck+=1 
     if tCheck >=10: 
      print "time out" 
    cleanThatStuffUp(conn.recv(1024)) # <-- see below 

這是返回到您的ssh客戶端垃圾的例子。

[1;24r[24;1H[24;1H[2K[24;1H[?25h[24;1H[24;1HProCurve Switch 2650# [24;1H[24;23H[24;1H[?5h[24;23H[24;23Hconfigure[24;23H[?25h[24;32H[24;0HE[24;1H[24;32H[24;1H[2K[24;1H[?5h[24;1H[1;24r[24;1H[1;24r[24;1H[24;1H[2K[24;1H[?25h[24;1H[24;1H 

還有退出代碼來處理之前每個「[」。所以爲了解決這個問題,我想出了一些正則表達式來清理所有這些「東西」。

procurve_re1 = re.compile(r'(\[\d+[HKJ])|(\[\?\d+[hl])|(\[\d+)|(\;\d+\w?)') 
procurve_re2 = re.compile(r'([E]\b)') 
procurve_re3 = re.compile(ur'[\u001B]+') #remove stupid escapes 

def cleanThatStuffUp(message): 
    message = procurve_re1.sub("", message) 
    message = procurve_re2.sub("", message) 
    message = procurve_re3.sub("", message) 
    print message 

現在,您可以開始輸入命令,只要確保每次使用recieveData()都清除緩衝區。

conn.send("\n") # Get past "Press any key" 
recieveData() 
2

如上你提到@dobbo要做invoke_shell()在通道上,這樣就可以執行多條命令。此外,HP ProCurve在輸出中具有ANSI轉義代碼,因此您必須將這些代碼除去。最後,HP ProCurve會拋出一個「按任意鍵繼續」的消息,您必須至少在某些設備上通過該消息。

我有一個HP的ProCurve處理這個庫https://github.com/ktbyers/netmiko

DEVICE_TYPE設置爲 「hp_procurve」。

Exscript也有某種ProCurve處理程序,儘管我還沒有深入到足以讓它工作。

相關問題