1.配置文件host.conf[webserver]host1=192.168.1.10,root,123456,22host2=192.168.1.11,root,123456,22[dbserver]db1=192.168.1.12,root,123456,22db2=192.168.1.13,root,123456,222.ssh远程命令脚本ssh.py#!/usr/bin/python# --*-- coding: utf-8 --*--import paramikoimport os, sysimport configparserfrom multiprocessing import Process, Lockfrom optparse import OptionParser   #解析命令行参数"""命令行格式如下:python.exe ssh.py -H host1,host2 -G webserver,dbserver -C "free -m"   # -C 后面命令必须双引号python.exe ssh.py -H host1,host2  -C "df -Th"python.exe ssh.py -G webserver,dbserver -C "ls -l""""#加载解析配置文件home_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))conf_file = home_dir + '\\conf\\cmd.conf'config = configparser.ConfigParser()config.read(conf_file)host1_info = config.get('webserver', 'host1').split(',')host2_info = config.get('webserver', 'host2').split(',')db1_info = config.get('dbserver', 'db1').split(',')db2_info = config.get('dbserver', 'db2').split(',')sections_list = config.sections()#print(config.options('dbserver'))host_dict = {'host1': host1_info, 'host2': host2_info, 'db1': db1_info, 'db2': db2_info}class MyProcess(Process):    def __init__(self, hostname, username, password, cmd, name, lock):        super().__init__()        self.hostname = hostname        self.username = username        self.password = password        self.cmd = cmd        self.name = name        self.lock = lock    def run(self):        with self.lock:            try:                ssh = paramiko.SSHClient()                # ssh.load_system_host_keys()                ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy)  # 不使用密钥认证                ssh.connect(hostname=self.hostname, username=self.username, password=self.password)                stdin, stdout, stderr = ssh.exec_command(self.cmd)  # 执行远程命令                print('%s 主机开始执行命令%s' % (self.name,self.cmd))                print(stdout.read().decode('utf-8'))                ssh.close()                print('%s主机执行结束\n' %self.name)            except Exception as e:                print(e)def cmd_parser():    """命令行解析"""    parser = OptionParser()    parser.add_option("-H", "--host", dest="host", help="执行远程命令的主机")    parser.add_option("-G", "--group", dest="group", help="执行远程命令的主机组")    parser.add_option("-C", "--command", dest="command", help="需要执行的远程命令")    (options, _) = parser.parse_args()    hosts = []    if options.host:        temp_hosts = options.host.split(',')        for i in temp_hosts:            if i in host_dict:                    hosts.append(i)    groups = []    if options.group:        temp_groups = options.group.split(',')        if temp_groups:            for i in temp_groups:                if i in sections_list:                    groups.append(i)    temp_group_list = []    if groups:        for i in groups:            temp_group_list += config.options(i)    if options.command:        cmd = options.command    else:        print('命令不存在,退出程序')        sys.exit(1)    return (hosts, temp_group_list, cmd)if __name__ == '__main__':    lock = Lock()    cmd_tuple = cmd_parser()    hosts = cmd_tuple[0]    groups = cmd_tuple[1]    cmd = cmd_tuple[2]    #print(cmd_tuple)    p_l = []    if hosts:        for host in hosts:            p = MyProcess(host_dict[host][0],host_dict[host][1],host_dict[host][2],cmd,host,lock)            p.daemon = True            p.start()            p_l.append(p)    if groups:        for host in groups:            p1 = MyProcess(host_dict[host][0],host_dict[host][1],host_dict[host][2],cmd,host,lock)            p.daemon = True            p1.start()            p_l.append(p1)    for i in p_l:        i.join()    print("所有进程执行结束")    sftp上传下载文件脚本#!/usr/bin/python# --*-- coding: utf-8 --*--import paramikoimport os, sysimport configparserfrom optparse import OptionParserfrom multiprocessing import Process,Lock"""命令行格式:本地是windows主机路径,远端是linux主机路径上传文件执行格式python.exe sftp.py -H host1,host2 -G webserver,dbserver -a put -l E:\python\oldboyday9\homework\bin\hyh.txt -r /home/kkjr/hyh.txtpython.exe sftp.py -H host1,host2 -a put -l E:\python\oldboyday9\homework\bin\hyh.txt -r /home/kkjr/hyh.txtpython.exe sftp.py -G webserver,dbserver -a put -l E:\python\oldboyday9\homework\bin\hyh.txt -r /home/kkjr/hyh.txt下载文件执行命令python.exe sftp.py -H host1 -a get -l E:\python\oldboyday9\homework\bin\hyh.txt -r /home/kkjr/hyh.txt"""bin_dir = os.path.dirname(os.path.abspath(__file__))    #上传下载文件存放目录设置成bin目录#加载解析配置文件home_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))conf_file = home_dir + '\\conf\\cmd.conf'config = configparser.ConfigParser()config.read(conf_file)host1_info = config.get('webserver', 'host1').split(',')host2_info = config.get('webserver', 'host2').split(',')db1_info = config.get('dbserver', 'db1').split(',')db2_info = config.get('dbserver', 'db2').split(',')sections_list = config.sections()#print(config.options('dbserver'))host_dict = {'host1': host1_info, 'host2': host2_info, 'db1': db1_info, 'db2': db2_info}class MyProcess(Process):    def __init__(self, hostname, username, password, port, cmd, localpath, remotepath):        super().__init__()        self.hostname = hostname        self.username = username        self.password = password        self.port = int(port)        self.cmd = cmd        self.localpath = localpath        self.remotepath = remotepath    def run(self):        """上传下载文件"""        try:            t = paramiko.Transport((self.hostname, self.port))            t.connect(username=self.username, password=self.password)            sftp = paramiko.SFTPClient.from_transport(t)            if self.cmd == 'put':                sftp.put(self.localpath, self.remotepath)            elif self.cmd == 'get':                sftp.get(self.remotepath, self.localpath)            else:                print('命令不存在')                sys.exit(1)        except Exception as e:            print(e)def cmd_parser():    """命令行解析"""    parser = OptionParser()    parser.add_option("-H", "--host", dest="host", help="执行远程命令的主机")    parser.add_option("-G", "--group", dest="group", help="执行远程命令的主机组")    parser.add_option("-a", "--action", dest="action", help="上传下载文件参数设置")    parser.add_option("-l", "--local", dest="local", help="本地文件路径参数设置")    parser.add_option("-r", "--remote", dest="remote", help="ftp服务器文件路径参数设置")    (options, _) = parser.parse_args()    #print(options.host,options.group,options.action,options.local,options.remote)    hosts = []    if options.host:        temp_hosts = options.host.split(',')        for i in temp_hosts:            if i in host_dict:                hosts.append(i)    groups = []    if options.group:        temp_groups = options.group.split(',')        if temp_groups:            for i in temp_groups:                if i in sections_list:                    groups.append(i)    temp_group_list = []    if groups:        for i in groups:            temp_group_list += config.options(i)    if options.action and options.local and options.remote:        cmd = options.action        localpath = options.local        remotepath = options.remote    else:        print('命令不存在,退出程序')        sys.exit(1)    return (hosts, temp_group_list, cmd, localpath, remotepath)if __name__ == '__main__':    cmd_tuple = cmd_parser()    hosts = cmd_tuple[0]    groups = cmd_tuple[1]    cmd = cmd_tuple[2]    localpath = cmd_tuple[3]    remotepath = cmd_tuple[4]    p_l = []    if hosts:        for host in hosts:            p = MyProcess(host_dict[host][0],host_dict[host][1],host_dict[host][2],host_dict[host][3],cmd,localpath,remotepath)            p.daemon = True            p.start()            p_l.append(p)    if groups:        for host in groups:            p1 = MyProcess(host_dict[host][0],host_dict[host][1],host_dict[host][2],host_dict[host][3],cmd,localpath,remotepath)            p1.daemon = True            p1.start()            p_l.append(p1)    for i in p_l:        i.join()    print("所有进程执行结束")