python小练习八——多线程的发布工具
来源:互联网 发布:python 处理get请求 编辑:程序博客网 时间:2024/05/28 09:33
题目要求
1、对机器进行分组
2、对指定组的机器进行批量操作(执行某条命令,上传下载文件)
3、要有操作日志
代码
#!/usr/bin/env python3import sys, paramiko, os, time, picklefrom multiprocessing import Process, Lockimport logginglogging.basicConfig(filename='dingyi.log', level=logging.INFO, format='%(asctime)s %(message)s', datefmt='%Y-%d-%m %I:%M:%S %p')class Dingyi(object): #定义远程传输文件和执行命令的类 def __init__(self, ip): self.ip = ip self.port = 22 self.name = 'root' self.password = '111111' def link(self): #连接 #self.ssh = paramiko.SSHClient() #self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #self.ssh.connect(hostname = self.ip, username = 'root', password = '111111') self.transport = paramiko.Transport((self.ip, self.port)) self.transport.connect(username = self.name, password = self.password) self.ssh = paramiko.SSHClient() self.ssh._transport = self.transport logging.info("connect %s" % self.ip) self.sftp = paramiko.SFTPClient.from_transport(self.transport) def close(self): #断开链接 self.transport.close() logging.info("close %s" % self.ip) def cmd(self, user_cmd): #执行命令 stdin, stdout, stderr = self.ssh.exec_command(user_cmd) result = str(stdout.read().decode()) res_err = str(stderr.read().decode()) if not res_err: logging.info("bash %s at %s success" % (user_cmd, self.ip)) return result else: logging.warning("bash %s at %s fail" % (user_cmd, self.ip)) return res_err def put(self, local_file_name, target_file_name): #上传文件 try: self.sftp.put(local_file_name, target_file_name) logging.info("put %s to %s" % (local_file_name, target_file_name)) except IsADirectoryError: print("%s文件读取错误,请输入文件\n" % local_file_name) logging.error("put:%s文件读取错误" % local_file_name ) except FileNotFoundError: print("%s文件没有找到\n" % local_file_name) logging.error("put:%s文件没有找到" % local_file_name) except OSError: print("%s目标目录不是文件\n" % target_file_name) logging.error("put:%s目标目录不是文件" % target_file_name) def get(self, target_file_name, local_file_name): #下载文件 try: self.sftp.get(target_file_name, local_file_name) logging.info('get %s to %s' % (target_file_name, local_file_name)) except IsADirectoryError: print("%s文件读取错误,请输入文件" % local_file_name) logging.error("get:%s文件读取错误" % local_file_name ) except FileNotFoundError: print("%s文件没有找到" % local_file_name) logging.error("get:%s文件读取错误" % local_file_name ) except OSError: print("%s目标目录不是文件" % target_file_name) logging.error("get:%s文件读取错误" % local_file_name ) def putdir(self, local_dir, target_dir): #上传目录 try: dir_list = os.listdir(local_dir) #检查本地目录,获取目录内所有目录和文件 except FileNotFoundError: print("没有找到此目录%s 或目标目录不正确" % local_dir) logging.error("putdir:没有找到此目录%s 或目标目录不正确" % local_dir) sys.exit() except NotADirectoryError: print("%s这不是个目录 或目标目录不正确" % local_dir) logging.error("putdir:%s这不是个目录 或目标目录不正确" % local_dir) sys.exit() for i in dir_list: #遍历目录内容 if local_dir[-1] != os.sep: #检查目录末尾是否有'/' local_dir += os.sep if target_dir[-1] != os.sep: target_dir += os.sep local_file = local_dir + i #将目录拼接成子目录 target_file = target_dir + i if os.path.isdir(local_file): #如果子目录是文件,则递归 target_dir_temp = target_dir + i local_dir_temp = local_dir + i cmd2 = "mkdir %s" % target_dir_temp a,b,c = self.ssh.exec_command(cmd2) time.sleep(0.1) #这里要暂停一下,因为在远程的时候,上传文件要比创建子目录快 self.putdir(local_dir_temp, target_dir_temp) else: #是文件,上传文件 self.put(local_file, target_file) def getdir(self, target_dir, local_dir): user_cmd = "ls -l %s" % target_dir #获取远程目录信息 res = self.cmd(user_cmd).strip() for i in res.split('\n'): #遍历远程目录 if target_dir[-1] != os.sep: #判断目录结尾是否有'/' target_dir = target_dir + os.sep if local_dir[-1] != os.sep: local_dir = local_dir + os.sep if i[0] == 'd': #如果是目录,在本地创建目录,并递归 dir_name = i.split()[-1] target_dir_temp = target_dir + dir_name local_dir_temp = local_dir + dir_name os.makedirs(local_dir_temp) self.getdir(target_dir_temp, local_dir_temp) elif i[0] == '-': #如果是文件,下载文件 file_name = i.split()[-1] target_file_name = target_dir + file_name local_file_name = local_dir + file_name self.get(target_file_name, local_file_name)def get_group(group_name): #获取机器IP地址组 with open("group", 'rb') as f: group_dict = pickle.load(f) try: return group_dict[group_name] except KeyError: return '输入的组名错误'def help(): #帮助文档 title = '''输入错入应输入 python3 dingyi -g 组名 -选项选项可以是:-cmd 命令-put 本地文件 远程目标文件-get 远程目标文件 本地文件-putdir 本地目录 远程目标目录-getdir 远程目标目录 本地目录''' print(title)def get_user_cmd(target_ip, l): #分析用户输入的命令 l.acquire() #进程锁 #当选项存在时,完成相应的操作 if '-cmd' in sys.argv: cmd_index = sys.argv.index('-cmd') try: #判断参数是否正确 user_cmd = sys.argv[cmd_index + 1] except IndexError: help() sys.exit() rel_cmd(target_ip, user_cmd) if '-get' in sys.argv: get_index = sys.argv.index('-get') try: target_file_name = sys.argv[get_index + 1] local_file_name = sys.argv[get_index + 2] except IndexError: help() sys.exit() rel_get(target_ip, target_file_name, local_file_name) if '-put' in sys.argv: put_index = sys.argv.index('-put') try: local_file_name = sys.argv[put_index + 1] target_file_name = sys.argv[put_index + 2] except IndexError: help() sys.exit() rel_put(target_ip, local_file_name, target_file_name) if '-getdir' in sys.argv: getdir_index = sys.argv.index('-getdir') try: target_dir = sys.argv[getdir_index + 1] local_dir = sys.argv[getdir_index + 2] except IndexError: help() sys.exit() rel_getdir(target_ip, target_dir, local_dir) if '-putdir' in sys.argv: putdir_index = sys.argv.index('-putdir') try: local_dir = sys.argv[putdir_index + 1] target_dir = sys.argv[putdir_index + 2] except IndexError: help() sys.exit() rel_putdir(target_ip, local_dir, target_dir) l.release() #解锁def rel_cmd(target_ip, user_cmd): #命令操作 dingyi = Dingyi(target_ip) dingyi.link() res = dingyi.cmd(user_cmd) dingyi.close() print(res)def rel_put(target_ip, local_file_name, target_file_name): #上传文件操作 dingyi = Dingyi(target_ip) dingyi.link() dingyi.put(local_file_name, target_file_name) dingyi.close()def rel_get(target_ip, target_file_name, local_file_name): #下载文件操作 dingyi = Dingyi(target_ip) dingyi.link() dingyi.get(target_file_name, local_file_name) dingyi.close()def rel_getdir(target_ip, target_dir, local_dir):#下载目录操作 dingyi = Dingyi(target_ip) dingyi.link() dingyi.getdir(target_dir, local_dir) dingyi.close()def rel_putdir(target_ip, local_dir, target_dir):#上传目录操作 dingyi = Dingyi(target_ip) dingyi.link() dingyi.putdir(local_dir, target_dir) dingyi.close()def run(): #程序主体 if '-g' in sys.argv: #判断是否输入主机组 group_index = sys.argv.index('-g') group_name = sys.argv[group_index + 1] else: help() sys.exit() #判断是否输入参数 if '-cmd' not in sys.argv and '-put' not in sys.argv and '-get' not in sys.argv and '-putdir' not in sys.argv and '-getdir' not in sys.argv: help() sys.exit() ip_list = get_group(group_name) l = Lock() process_list = [] for i in ip_list: t = Process(target = get_user_cmd, args = (i,l, )) process_list.append(t) for i in process_list: i.start()if __name__ == "__main__": run()
阅读全文
0 0
- python小练习八——多线程的发布工具
- Python多线程小练习
- python基础(八)——多线程
- Python小练习四——计算器
- python小练习六——小游戏
- python的练习小例子
- python练习(八)
- 小练习 ---- 简单的多线程模拟
- 一个关于多线程同步的小练习。
- python 爬虫练习 多线程的运用
- python小练习七——支持多用户在线的FTP程序
- python学习之小的练习程序
- python 不超过20行的小练习
- python正则表达式的小练习
- 【NLP】单词纠错——python小练习
- Python小练习五——ATM系统
- 小练习—判断某个年是否是瑞年(python&java)
- [python]一个简单的听写练习工具
- 观察者模式与推拉模型
- redis的 rdb 和 aof 持久化的区别
- 1118. Birds in Forest (25)
- 模拟latch:cbc等待
- Learning of javascript!
- python小练习八——多线程的发布工具
- java[min,max]之间的随机整数
- anaconda 安装opencv后,加载摄像头遇到的问题
- Floyd算法求无向图最小环
- tcp 三次握手和四次挥手【转】
- 网络基础零碎笔记
- HTTP协议
- 强连通分量Kosaraju算法实现
- shell 高级编程(1)