python多进程线程练习:主机批量管理

需求:
1.主机信息配置文件用configparser解析
2.可批量执行命令,上传文件,结果实时返回
3.主机用户名密码、端口可以不同
4.执行远程命令使用paramiko模块
5.多台主机链接创建多个进程并发,单台主机上的多条执行命令使用多线程并发

一、安装模块
paramiko模块是遵循python模块标准的openssh协议模块,可以使用pip快速安装。
首先需安装pip工具,windows的python安装包一般没有集成pip,需单独安装
下载pip源码包:
https://pypi.python.org/pypi/pip#downloads
打开windows cmd,打开后进入
解压源码包后进入源目录
执行:
python setup.py install
安装完成后,pip安装paramiko
pip install paramiko
安装成功后,开始code

二、生成配置文件:

def addhost():
    while True:
        num=input('Add host to conf.ini,Input last num,or  q|Q to continue :')
        if num== 'q' or 'Q':
            break
        else:
            ip=str('192.168.0.%s'%num)
            config.add_section(ip)
            config.set(ip,'username','root')
            config.set(ip,'password','xxxxxxxxxxx')
        config.write(sys.stdout)
        config.write(open('sample.ini','w'))

addhost()

密码正好是统一的不用改了。生成配置文件如下:
这里写图片描述

三、加载配置文件,连接主机执行命令,所有代码如下:

from multiprocessing import Process
import configparser,sys,threading,os
import paramiko
config=configparser.ConfigParser()
config.read(u'sample.ini')
host_list=config.sections()

'''
configparser用法:
#config.set('section','username','root')   #给大标题内的key赋值
# print(config.get("size","size"))  #查看大标题内的指定小标题
# print(config.sections()  )   #查看所有section大标题
'''

def addhost():
    while True:
        num=input('\033[0;32mAdd host to conf.ini,Input last num,or  q|Q to continue :\033[0m')
        if num== 'q' or 'Q':
            break
        else:
            ip=str('192.168.0.%s'%num)
            config.add_section(ip)
            config.set(ip,'username','root')
            config.set(ip,'password','yinwenqin')
        config.write(sys.stdout)
        config.write(open('sample.ini','w'))

def ssh_conn(host,cmd_list):
    usr=config.get(host,'username')
    passwd=config.get(host,'password')
    print('\033[1;32mProcess ID:\033[0m',os.getpid())
    ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
    ssh.connect(hostname=host, port=22, username=usr, password=passwd)
    for c in cmd_list:
        t=threading.Thread(target=exec,args=(host,ssh,c,))
    #将连接实例传递给线程执行
        t.start()
        t.join()
    ssh.close()

def exec(host,ssh,c):
    stdin, stdout, stderr = ssh.exec_command(c)  # 执行命令,分别保存标准输入、标准输出、标准错误结果到变量
    # 获取命令结果
    result = stdout.read().decode()
    print('\033[1;33mExec thread ID:\033[0m',threading.current_thread())
    print('\033[1;33mHost %s exec cmd <<%s>> result>>:\033[0m' %(host,c))
    print(result)

def sftp_conn(host,cmd_list):
    usr=config.get(host,'username')
    passwd=config.get(host,'password')
    print('\033[1;32mProcess ID:\033[0m',os.getpid())
    transport = paramiko.Transport((host,22))
    transport.connect(username=usr,password=passwd)
    sftp = paramiko.SFTPClient.from_transport(transport)

    filename_list=cmd_list[1:]
    for file in filename_list:
        if cmd_list[0] == 'put':
            t=threading.Thread(target=put,args=(host,sftp,file,))
            t.start()
            t.join()

        elif cmd_list[0] == 'get':
            t=threading.Thread(target=get,args=(host,sftp,file,))
            t.start()
            t.join()

    transport.close()


def put(host,sftp,file):
    sftp.put(file,'/root/%s' %file)
    print('\033[1;33mExec thread ID:\033[0m',threading.current_thread())
    print('\033[1;33mHost %s exec cmd <<put %s>> result>>:\033[0m' %(host,file))
    print('\033[1;33mFile info:\033[0m \n',os.stat(file))

def get(host,sftp,file):
    sftp.get('/root/%s' %file, 'D:\Python\Myscript\process & threading\%s' %file)
    print('\033[1;33mExec thread ID:\033[0m',threading.current_thread())
    print('\033[1;33mHost %s exec cmd << get %s>> result>>:\033[0m' %(host,file))
    print('\033[1;33mFile info:\033[0m \n',os.stat('D:\Python\Myscript\process & threading\%s' %file))

if __name__ == '__main__':
    addhost()
    while True:
        try:
            print('\033[0;31mHosts list:\033[0m')
            print(host_list)
            choice=input('\033[0;32mChoose host to login:( divide multi hosts by space ):\033[0m \n')
            if len(choice)==0:continue
            choice_list=choice.split()
            print(choice_list)
            choice2=input('\033[0;32m 1.Exec cmd \n2.Put/get file \nPlease choose \033[0m \n ')
            print(choice2)
            cmd=input('\033[0;32mInput cmd ( <;> to devide cmds , <space> to divide files ):\033[0m \n')
            print(cmd)
            if int(choice2) == 1:
                cmd_list=cmd.split(';')  #use ';' to devide cmd str
                for i in choice_list:
                    print(i)
                    p=Process(target=ssh_conn,args=(i,cmd_list))
                    p.start()
                    p.join()

            elif int(choice2) == 2:
                cmd_list=cmd.split()  #use ';' to devide cmd str
                for i in choice_list:
                    print(i)
                    p=Process(target=sftp_conn,args=(i,cmd_list))
                    p.start()
                    p.join()


        except Exception as e:
            print('Error:',e)

实现了批量连接多个主机,在每个主机上同时执行多条命令,上传或下载多个文件。

运行效果:
这里写图片描述

老爷本开8台虚拟机一个IDE跑了这么久不容易啊,快热炸了,路过顶一下再走呗~
这里写图片描述]![这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值