zoukankan      html  css  js  c++  java
  • Python 实现远程服务器批量执行命令

     paramiko 远程控制介绍

    Python paramiko是一个相当好用的远程登录模块,采用ssh协议,可以实现linux服务器的ssh远程登录。首先来看一个简单的例子

    import paramiko
    #实例化ssh客户端
    ssh = paramiko.SSHClient()
    #创建默认的白名单
    policy = paramiko.AutoAddPolicy()
    #设置白名单
    ssh.set_missing_host_key_policy(policy)
    #链接服务器
    ssh.connect(
        hostname = "192.168.2.186", #服务器的ip
        port = 22, #服务器的端口
        username = "root", #服务器的用户名
        password = "123" #用户名对应的密码
    )
    #远程执行命令
    stdin,stdout,stderr = ssh.exec_command("ls")
        #exec_command 返回的对象都是类文件对象
        #stdin 标准输入 用于向远程服务器提交参数,通常用write方法提交
        #stdout 标准输出 服务器执行命令成功,返回的结果  通常用read方法查看
        #stderr 标准错误 服务器执行命令错误返回的错误值  通常也用read方法
    #查看结果,注意在Python3 字符串分为了:字符串和字节两种格式,文件返回的是字节
    result = stdout.read().decode()
    
    print(result)

    这是一段最简单的paramiko的代码,其中比较难理解的就是白名单概念,所谓的白名单就是ssh的know_hosts文件,用来记录paramiko可以信任的远程主机,在

    paramiko当中,需要生成和采用两个步骤,来避免在远程链接的时候,被询问是否信任远程登录的服务器。

    threaing多线程介绍

    想要学习多线程,先要明白:

      进程:是程序的一次运行,我们运行一个程序,就会形成一个进程,进程有独立的内存空间,也被称为重量级进程。

      线程:线程是进程下的一个分支,也被称为轻量级进程。

    threading是python多线程的基础模块,也可以说Python程序员接触多线程最初接触的模块,

    我们来看一下threading最基础的案例

    为了好理解我们来了解前置代码的编写

    最简单的例子:

     1 from time import sleep
     2 #通过这个例子我们来看计算机正常情况下的执行顺序 从左往右,从上到下
     3 def loop0():
     4     print("loop 0 is start")
     5     sleep(3)
     6     print("loop 0 is down")
     7 
     8 def loop1():
     9     print("loop 1 is start")
    10     sleep(2)
    11     print("loop 1 is down")
    12 
    13 def main():
    14     print("all is start")
    15     loop0()
    16     loop1()
    17     print("all is down")
    18 
    19 if __name__ == "__main__":
    20     main()

    代码优化过的例子:

    from time import sleep
    
    def loop(num,sleeptime):
        """
        当前函数作为功能函数
        :param num: 函数的编号
        :param sleeptime:  睡眠的时间
        """
        print("loop %s is start"%num)
        sleep(sleeptime)
        print("loop %s is done"%num)
    
    def main():
        sleep_list = [3,2] #睡眠时间
        lenth = len(sleep_list) #获取列表长度
        print("all is start") 
        for i in range(lenth):
            loop(i,sleep_list[i]) #按照列表长度和列表内容调用函数
        print("all is down")
    
    
    if __name__ == "__main__":
        main()

    多线程调用的例子:

     1 import threading
     2 from time import sleep
     3 
     4 def loop(num,sleeptime):
     5     """
     6     当前函数作为功能函数
     7     :param num: 函数的编号
     8     :param sleeptime:  睡眠的时间
     9     """
    10     print("loop %s is start"%num)
    11     sleep(sleeptime)
    12     print("loop %s is done"%num)
    13 
    14 def main():
    15     sleep_list = [3,2] #睡眠时间
    16     lenth = len(sleep_list) #获取列表长度
    17     thread_list = []
    18     print("all is start")
    19     for i in range(lenth):
    20         #threading.Thread 就是用线程来执行我们的功能
    21         t = threading.Thread(target = loop,args = (i,sleep_list[i])) #按照列表长度和列表内容调用函数
    22         thread_list.append(t) #将生成的线程添加到列表里
    23     for t in thread_list:
    24         t.start() #开始执行线程
    25     for t in thread_list:
    26         t.join()  #挂起线程,到所有线程结束
    27     print("all is down")
    28         

    通过上面例子的执行,我们需要掌握以几个点:

      1、threading.Thread方法用来创建线程,线程被创建的时候没有执行,需要通过start方法执行

      2、多线程调用实际上就是把原有的功能发到线程上面去跑,所以我们使用多线程,功能要写成函数

      3、Python的多线程是异步并发,而不是大家理解的并行,在这里

        并发:指的是同时出发,不同时执行

        并行:指的是同时进行,不一定同时出发

      希望各位同学注意上面的三点,而值得大家思考的就是上面代码最后的for循环可以简化吗?为啥?

    paramiko+threading 实现远程服务器批量执行命令

    完成上面的代码实例,我们进行代码的整合,完成远程服务器批量执行命令的效果

     1 #coding:utf-8
     2 
     3 import sys
     4 import paramiko
     5 import threading
     6 
     7 def getConnection(ip,username,password,command,port = 22):
     8     """
     9     :param ip: 服务器的ip
    10     :param username:  服务器的用户名称
    11     :param password:  服务器的密码
    12     :param CMD:  服务器的命令
    13     :param port:  服务器的端口
    14     """
    15     ssh = paramiko.SSHClient()
    16     policy = paramiko.AutoAddPolicy()
    17     ssh.set_missing_host_key_policy(policy)
    18     ssh.connect(
    19         hostname = ip,  # 服务器的ip
    20         port = port,  # 服务器的端口
    21         username = username,  # 服务器的用户名
    22         password = password  # 用户名对应的密码
    23     )
    24     stdin, stdout, stderr = ssh.exec_command(command)
    25 
    26     result = stdout.read().decode()
    27 
    28     error = stderr.read().decode()
    29 
    30     print("+++++++++++++++++++++++start++++++++++++++++++++")
    31     print("[connect success] | ip : %s" % ip)
    32     print("result: \n %s"%result)
    33     if error != " ":
    34         print("error: \n %s"%error)
    35     print("+++++++++++++++++++++++done++++++++++++++++++++")
    36 
    37     ssh.close()
    38 #我们采用多线程
    39 def main(host_list,command):
    40     thread_list = []
    41     for ip,username,password in host_list:
    42         thread = threading.Thread(target = getConnection, args = (ip,username,password,command))
    43         thread_list.append(thread)
    44     for t in thread_list:
    45         t.start()
    46     for t in thread_list:
    47         t.join()
    48 
    49 
    50 if __name__ == "__main__":
    51     host_list = [
    52         ("192.168.2.186", "root", "123"),
    53         ("192.168.2.88", "root", "123"),
    54     ]
    55     command = sys.argv[1]
    56     main(host_list,command)

    在这当中,我们使用了sys.argv方法来接收脚本外面执行的参数,当然,我们也可以将host_list写到一个配置文件当中使用。执行效果如下:

  • 相关阅读:
    01.Markdown学习
    微信小程序开发基础
    如何在本地搭建微信小程序服务器
    Golang | 报错
    Golang | 扩展
    Golang | 基础
    Golang | 基础
    Golang | 基础
    Chrome——书签同步码云
    Rustlings_structs
  • 原文地址:https://www.cnblogs.com/bianjinhui/p/9801491.html
Copyright © 2011-2022 走看看