执行环境,windows下执行
bin目录start.py
import os,sys BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) print(BASE_DIR) from core import core if __name__ == "__main__": core.run()
conf目录setlog.py,setting.py
import logging import os log_dir=os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),'logs','host_log') def get_logger(msg,f): logger = logging.getLogger() fh = logging.FileHandler(f)#设置日志写位置,f为日志文件 sh = logging.StreamHandler() logger.setLevel(logging.DEBUG) # 设定日志输出等级 fm = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") logger.addHandler(fh) logger.addHandler(sh) fh.setFormatter(fm) sh.setFormatter(fm) logger.debug(msg)#接收消息 return logger
"""配置文件""" msg_dic = { "g1":{ "h1":{"IP":"192.168.0.55", "username":"root", "password":"xiangshang", "port":10809}, "h2":{"IP":"192.168.0.50", "username":"root", "password":"xiangshang", "port":10809}, } }
core目录core.py
"""核心代码""" from conf import settings from conf import setlog import paramiko import threading import os class REMOTE_HOST(object): #远程操作主机 def __init__(self, host, port ,username, password, cmd): self.host = host self.port = port self.username = username self.password = password self.cmd = cmd def run(self): """起线程连接远程主机后调用""" cmd_str = self.cmd.split()[0] if hasattr(self, cmd_str): #反射 eg:调用put方法 getattr(self, cmd_str)() else: #setattr(x,'y',v)is equivalent to ``x.y=v'' setattr(self, cmd_str, self.command) getattr(self, cmd_str)() #调用command方法,执行批量命令处理 def command(self): """批量命令处理""" ssh = paramiko.SSHClient() #创建ssh对象 #允许连接不在know_hosts文件中的主机 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(hostname=self.host,port=self.port,username=self.username,password=self.password) stdin,stdout,stderr = ssh.exec_command(self.cmd) result = stdout.read() print("%s".center(50, "-") % self.host) print(result.decode()) ssh.close() def put(self): """上传文件""" print("example:put D:11.txt") filename = self.cmd.split()[1] #要上传的文件 if not os.path.isfile(filename):#判断是否有此文件 print("no file") return transport = paramiko.Transport((self.host, self.port)) transport.connect(username=self.username, password=self.password) sftp = paramiko.SFTPClient.from_transport(transport) sftp.put(filename, os.path.basename(filename)) #print("put sucesss") setlog.get_logger(os.path.basename(filename)+"upload successful!",setlog.log_dir)#记录上传日志 transport.close() def show_host_list(): """通过选择分组显示主机名与IP""" for index, key in enumerate(settings.msg_dic): print(index + 1, key, len(settings.msg_dic[key])) while True: choose_host_list = input(">>>(请选择主机例如:g1):").strip() host_dic = settings.msg_dic.get(choose_host_list) if host_dic: #print(host_dic) for key in host_dic: print(key, host_dic[key]["IP"]) return host_dic else: print("NO exit this group!") def interactive(choose_host_list): """根据选择的分组主机起多个线程进行批量交互""" thread_list = [] while True: print(r"上传文件命令:put D:11.txt,如需执行命令直接输入") cmd = input(">>>!").strip() if cmd: for key in choose_host_list: host, port, username, password = choose_host_list[key]["IP"], choose_host_list[key]["port"], choose_host_list[key]["username"], choose_host_list[key]["password"] func = REMOTE_HOST(host, port, username, password, cmd) # 实例化类 t = threading.Thread(target=func.run) # 起线程 t.start() thread_list.append(t) for t in thread_list: t.join() # 主线程等待子线程执行完毕 else: continue def run(): choose_host_list = show_host_list() interactive(choose_host_list)
logs目录文件文件自动生成,