【问题标题】:How to run in parallel with one ssh session using paramiko如何使用 paramiko 与一个 ssh 会话并行运行
【发布时间】:2016-04-11 03:25:08
【问题描述】:

Previous details
我需要在交换机上 ssh 以 ping 不同的主机。早些时候我为每个主机启动了一个线程,但结果很容易超过最大 ssh 连接数,所以我根据this 创建了一个交互式 shell 会话。但是当我并行运行时,它在发送第一个命令后一直挂在那里。我不知道如何解决这个问题。
下面列出的简化代码:

import paramiko
import time
from paramiko import SSHClient
from multiprocessing.dummy import Pool

def rping(src, user, passwd, dst):

    def command(des):
        chan.send('ping -s 64 -t 1500 %s\r\n' % des)
        time.sleep(3)
        resp = chan.recv(9999)
        print resp

    ssh = SSHClient()
    ssh.load_system_host_keys()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(src, 22, user, passwd, timeout=3)

    chan = ssh.invoke_shell()

    pool = Pool()
    pool.map(command, dst)
    pool.close()
    pool.join()


if __name__ == '__main__':
    print time.ctime()

    src = '10.130.1.121'
    user = 'user'
    passwd = 'password'
    dst = ['10.130.1.122', '10.130.1.123', 10.130.1.124'']
    rping(src, user, passwd, dst)

    print time.ctime()

【问题讨论】:

    标签: python python-2.7 ssh parallel-processing paramiko


    【解决方案1】:

    请记住,使用multiprocessing.dummy 实际上是在使用threading 模块。 鉴于此,您的 command 函数不会返回任何内容。

    def rping(src, user, passwd, dst):
        def command(des):
            chan = ssh.invoke_shell()  # new channel 
            chan.send('ping -t 64 -s 1500 -c 3 %s\r\n' % des)
            time.sleep(3)
            resp = chan.recv(9999)
            chan.close()  # close channel
            return resp
    
        ssh = SSHClient()
        ssh.load_system_host_keys()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(src, 22, user, passwd, timeout=3)
    
        pool = Pool(len(dst))
        result = pool.map(command, dst)
        pool.close()
        pool.join()
        ssh.close()  # close SSH client
        return result
    

    【讨论】:

    • 进程仍然挂起,但如果我用for 循环替换pool.map(),它运行良好,但耗时更多
    • 我看到 ping 参数似乎被交换了,实际上命令永无止境。编辑了修复它的答案并添加了-c 3,因此只发送了 3 个 ICMP 回显请求。
    • 如果未指定,则默认数据包数为 5。该脚本使用 for loop 串行运行良好,但失败并使用 pool.map() 并行挂在那里
    • 好的,我明白了,您必须为每个命令/迭代定义一个新通道。在 for 循环上运行另一种方式显然可以正常工作。请参阅上面的编辑。
    • 不行,好像一个ssh客户端只能创建一个通道,返回ChannelException: (4, 'Resource shortage')@valtuarte
    猜你喜欢
    • 2021-12-12
    • 2010-12-27
    • 1970-01-01
    • 2020-08-16
    • 2015-05-20
    • 2016-07-29
    • 2014-11-15
    • 2010-12-10
    • 1970-01-01
    相关资源
    最近更新 更多