web-dev-qa-db-ja.com

Paramikoを使用して一度に複数のSSH接続を作成する

以下のコードは、SSHを介して1台のマシンでgrepを実行し、結果を出力します。

import sys, os, string
import paramiko

cmd = "grep -h 'king' /opt/data/horror_20100810*"

ssh = paramiko.SSHClient()
ssh.set_missing_Host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('10.10.3.10', username='xy', password='xy')
stdin, stdout, stderr = ssh.exec_command(cmd)
stdin.write('xy\n')
stdin.flush()

print stdout.readlines()

5台のマシンを一度にgrepするには(大きな遅延が発生しないように)、すべてを5つの変数に入れて、すべて出力するよりもどうすればよいですか。

18
Whit3H0rse

呼び出しを別々のスレッド(またはプロセスですが、それはやり過ぎです)に入れる必要があります。これには、コードを関数に含める必要があります(とにかく良い考えです。モジュールの上部に実質的なコードを配置しないでください)。レベル)。

例えば:

import sys, os, string, threading
import paramiko

cmd = "grep -h 'king' /opt/data/horror_20100810*"

outlock = threading.Lock()

def workon(Host):

    ssh = paramiko.SSHClient()
    ssh.set_missing_Host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(Host, username='xy', password='xy')
    stdin, stdout, stderr = ssh.exec_command(cmd)
    stdin.write('xy\n')
    stdin.flush()

    with outlock:
        print stdout.readlines()

def main():
    hosts = ['10.10.3.10', '10.10.4.12', '10.10.2.15', ] # etc
    threads = []
    for h in hosts:
        t = threading.Thread(target=workon, args=(h,))
        t.start()
        threads.append(t)
    for t in threads:
        t.join()

main()

5つを超えるホストがある場合は、代わりに「スレッドプール」アーキテクチャとワークユニットのキューを使用することをお勧めします。ただし、5つだけの場合は、「専用スレッド」モデルに固執する方が簡単です(特に、標準ライブラリにスレッドプールがないため、 threadpool ..のようなサードパーティパッケージが必要になります。 。またはもちろんあなた自身の多くの微妙なカスタムコード;-)。

34
Alex Martelli