使用 Paramiko 一次创建多个 SSH 连接

新手上路,请多包涵

下面的代码通过 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 五台机器(这样我就不会有重大延迟),而不是将所有这些都放在五个变量中并将它们全部打印出来。

原文由 Whit3H0rse 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1k
2 个回答

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

例如:

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

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

原文由 Alex Martelli 发布,翻译遵循 CC BY-SA 2.5 许可协议

#! /usr/bin/env python3
import sys, os, string, threading
try:
    import paramiko
    #import paramiko package
except:
    im = input("Paramiko module is missing. Do you want to install[Y/N]:")
    im = im.upper()
    if im == "Y":
        try:
            try:
                os.system("pip install paramiko")
            except:
                os.system("pip3 install paramiko")
        except:
            print("Please install paramiko package manually")
    else:
        print("Rerun and type 'y' to install")

#Running paramiko module with interactive password sending function
#this function helps to send password when sudo command is executed
def sudossh():
    host = "type host ip"
    port = 22
    username = "type username"
    password = "type password"
    try:
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(host, port, username, password)
        ssh.get_transport()
        #In this example we will run HTTP module on server in port 80
        command = "sudo su -c 'sudo python -m SimpleHTTPServer 80'"
        print(f"Running: {command}\n")
        stdin, stdout, stderr = ssh.exec_command(command=command,get_pty=True)
        stdin.write("password\n")
        print("sent password\n")
        print("HTTP service is running now\n")
        stdin.flush()
        if stderr.channel.recv_exit_status() != 0:
            print(f"Error: {stderr.readlines()}")
        else:
            print(f"Output: \n{stdout.readlines()}")
        ssh.close()
    except Exception as err:
        print(str(err));
        print("Thanks for using my application");

#Running another paramiko module with interactive password sending function
def grepverification():
    host = "type host ip"
    port = 22
    username = "type username"
    password = "type password"
    try:
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(host, port, username, password)
        ssh.get_transport()
        #Open new session and check port 80 status on server
        command = "sudo su -c 'netstat | grep 80'"
        print(f"Running: {command}\n")
        stdin, stdout, stderr = ssh.exec_command(command=command,get_pty=True)
        stdin.write("password\n")
        print("sent password\n")
        print("Connection is established. Check below output\n")
        stdin.flush()
        if stderr.channel.recv_exit_status() != 0:
            print(f"Error: {stderr.readlines()}")
        else:
            print(f"Output: \n{stdout.readlines()}")
        ssh.close()
    except Exception as err:
        print(str(err));
        print("Thanks for using my application");

def main():
    #Multithreading helps to run both at a same time. Useful for verification.
    # creating thread
    th1 = threading.Thread(target=sudossh)
    th2 = threading.Thread(target=grepverification)
    # starting thread 1
    th1.start()
    # starting thread 2
    th2.start()
    # wait until thread 1 is completely executed
    th1.join()
    # wait until thread 2 is completely executed
    th2.join()
    # both threads completely executed
    print("Completed!")
#you can use for loop to reduce lines but for understanding & smooth multithreading process will keep it as separate functions
#Comments are welcome. Thanks. Follow me on https://www.linkedin.com/in/dinesh-kumar-palanivelu-858441128/
#you need to change line - 23-26,36,51-54,64

if __name__=='__main__':
       main()


原文由 Dinesh Kumar Palanivelu 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题