22

下面的代码通过 SSH 在一台机器上运行 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()

我怎样才能一次 grep 五台机器(这样我不会有很大的延迟),而不是将所有这些放在五个变量中并将它们全部打印出来。

4

3 回答 3

41

您需要将调用放入单独的线程(或进程,但这将是矫枉过正),这反过来又要求代码在一个函数中(无论如何这是一个好主意:在模块的顶部没有大量代码等级)。

例如:

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()

如果您有超过五台主机,我建议您改用“线程池”架构和工作单元队列。但是,只有五个,坚持“专用线程”模型更简单(特别是因为标准库中没有线程池,所以你需要像threadpool这样的第三方包......或者很多微妙的自定义当然是你自己的代码;-)。

于 2010-08-14T23:03:28.830 回答
0

在我的情况下,我必须在具有一个 ip 和端口的服务器上执行命令,完成后需要对其他 ip 和不同端口执行 sftp。条件是由于端口转发,在对另一个 ip 执行 sftp 时,一个连接应该是活动的。

两个连接都可以单独工作,但是在结合两个 sftp 连接时不起作用。

于 2020-07-22T05:59:17.390 回答
-1

只需在for循环中运行所有内容,并且不要忘记在继续下一次迭代之前关闭标准输入。也就是说,在行后stdin.flush()添加行stdin.close()

于 2016-09-02T19:53:43.057 回答