2017-01-06 88 views
0

編輯: 使用片斷下面我遇到的幾個問題執行二進制文件在Python腳本

import paramiko, threading 

ssh=paramiko.SSHClient() 
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 

def connectAndCMD(command): 
    ssh.connect('127.0.0.1',22,'MY_USER','MY_SSH_PASS') 
    stdin, stdout, stderr = ssh.exec_command(command) 
    print stdout.read() 

commandList=[ 
    "pwd", 
    "whoami", 
    "ls", 
    "echo hello", 
    "ping google.com", 
    "ifconfig | grep Bcast | awk {'print $2'}" 
] 
for command in commandList: 
    print '[',command, '] command thread started' 
    t=threading.Thread(target=connectAndCMD,args=(command,)) 
    t.start() 

在控制檯中我看到: SSHException:不存在會話 奇怪的是,當我減少列表的大小隻是一些命令,減少了線程數量,我能夠看到隨機線程的某個ssh命令的輸出,但是腳本無限期地掛起。什麼是問題,我該如何解決這個問題?

這是樣機,但在我實際的程序我正在做的線程來運行只是不同的參數/選項

+0

也許不相關:''/ BIN_FILE'+ binFileParam'應該拋出無效字符串+整數串聯。應該是''/ BIN_FILE {}'。格式(binFileParam)' –

+0

好的!是的,我只是錯誤地改寫了。 – zweed4u

+0

您可能遇到[this](http://stackoverflow.com/documentation/ssh/2926/debugging-ssh-problems/25955/ssh-exchange-identification-connection-closed-by-remote-host#t=201701061520463626447 )或[this](http://stackoverflow.com/documentation/ssh/2926/debugging-ssh-problems/25954/ssh-exchange-identification-read-connection-reset-by-peer#t=201701061520463626447)。 – Kenster

回答

1

的問題是,您試圖重新驗證每個命令的ssh連接相同的命令。 SSH使用單個傳輸連接(通常是TCP,但理論上是其他的)來複用多個ssh級別的通道,這些通道運行命令,管道和外殼等。 SSHClient.connect將打開傳輸連接,驗證服務器(注意丟失的主機密鑰策略 - 您使用了一個相當不安全的策略)並驗證客戶端(在您的情況下爲密碼)。

之後,客戶端可以打開任意數量的ssh級別的通道來完成工作。每個exec_command打開一個通道,在服務器上啓動一個shell,運行一個命令並關閉該通道。但由於這些通道是多路複用的,它們可以並行運行,並且是多線程的好選擇。

import paramiko, threading 

ssh=paramiko.SSHClient() 
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
ssh.connect('127.0.0.1',22,'MY_USER','MY_SSH_PASS') 

def connectAndCMD(command): 
    stdin, stdout, stderr = ssh.exec_command(command) 
    print stdout.read() 

commandList=[ 
    "pwd", 
    "whoami", 
    "ls", 
    "echo hello", 
    "ping google.com", 
    "ifconfig | grep Bcast | awk {'print $2'}" 
] 
for command in commandList: 
    print '[',command, '] command thread started' 
    t=threading.Thread(target=connectAndCMD,args=(command,)) 
    t.start() 

UPDATE

由於SSH服務器會限制你可以使用一個線程池,以確保您保持在限制下同時命令的數量。

import paramiko 
import multiprocessing.pool 

ssh=paramiko.SSHClient() 
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
ssh.connect('127.0.0.1',22,'MY_USER','MY_SSH_PASS') 

def connectAndCMD(command): 
    stdin, stdout, stderr = ssh.exec_command(command) 
    return command, stdout.read(), stderr.read() 

commandList=[ 
    "pwd", 
    "whoami", 
    "ls", 
    "echo hello", 
    "ping google.com", 
    "ifconfig | grep Bcast | awk {'print $2'}" 
] 

pool = multiprocessing.pool.ThreadPool(min(10, len(commandList)) 
for command, out, err in pool.map(connectAndCMD, commandList, chunksize=1): 
    print((command, out, err)) 
pool.close() 
pool.join() 
+0

太棒了!謝謝你,最後一個問題; paramiko有沒有限制?向列表中添加命令時它成功完成了一些線程,但是在一些線程中:ChannelException:(1,'Administratively prohibited')被拋出,並且SSHException:無法打開通道。看來10個線程是成功輸出的最多線程。 – zweed4u

+0

這是從服務器端返回的通道錯誤代碼。我猜服務器端的服務器數量有限,但是我之前並沒有碰到它......而且我很驚訝這個數字太低了! – tdelaney

+0

我的linux ssh配置有一個MaxSessions配置參數:_MaxSessions - 指定每個網絡連接允許的最大打開會話數。默認值是10_ SSH術語很奇怪,但我認爲這意味着每個會話的頻道。而且由於默認值是10,所以它似乎很合適。 – tdelaney

相關問題