热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python小练习八——多线程的发布工具

题目要求1、对机器进行分组2、对指定组的机器进行批量操作(执行某条命令,上传下载文件)3、要有操作日志代码#!usrbinenvpython3importsys,par

题目要求

1、对机器进行分组
2、对指定组的机器进行批量操作(执行某条命令,上传下载文件)
3、要有操作日志

代码
#!/usr/bin/env python3
import sys, paramiko, os, time, pickle
from multiprocessing import Process, Lock
import logging

logging.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()


推荐阅读
  • PHP程序员玩转Linux系列 搭建FTP代码开发环境
    PHP程序员玩转Linux系列搭建FTP代码开发环境-PHP程序员玩转Linux系列文章:有些同学可能觉得我写的都是啥yum安装的,随便配置一下而已,没啥技术含量,我的目的是让大家 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • linux ftp 线程数设置,Linux搭建ftp在windows下这么访问,需要怎么设置【设置vsftp最大连接数和每个ip的最大连接数】...
    文章来源:http:zhidao.baidu.comlink?urlLOfStD1kcxGhI_D5qC7oka3_4QZc1nn1SJwWaSd4onWoVl5Wt ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 本文介绍了Python对Excel文件的读取方法,包括模块的安装和使用。通过安装xlrd、xlwt、xlutils、pyExcelerator等模块,可以实现对Excel文件的读取和处理。具体的读取方法包括打开excel文件、抓取所有sheet的名称、定位到指定的表单等。本文提供了两种定位表单的方式,并给出了相应的代码示例。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • 【MicroServices】【Arduino】装修甲醛检测,ArduinoDart甲醛、PM2.5、温湿度、光照传感器等,数据记录于SD卡,Python数据显示,UI5前台,微服务后台……
    这篇文章介绍了一个基于Arduino的装修甲醛检测项目,使用了ArduinoDart甲醛、PM2.5、温湿度、光照传感器等硬件,并将数据记录于SD卡,使用Python进行数据显示,使用UI5进行前台设计,使用微服务进行后台开发。该项目还在不断更新中,有兴趣的可以关注作者的博客和GitHub。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • php支持中文文件名
    2019独角兽企业重金招聘Python工程师标准大家可能遇到过上传中文文件名的文件,或者读取中文目录时不能读取,出现错误的情况这种情况是因为php自动将中文字符转成了utf8 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
  • 恶意软件分析的最佳编程语言及其应用
    本文介绍了学习恶意软件分析和逆向工程领域时最适合的编程语言,并重点讨论了Python的优点。Python是一种解释型、多用途的语言,具有可读性高、可快速开发、易于学习的特点。作者分享了在本地恶意软件分析中使用Python的经验,包括快速复制恶意软件组件以更好地理解其工作。此外,作者还提到了Python的跨平台优势,使得在不同操作系统上运行代码变得更加方便。 ... [详细]
  • FTP服务ftp的报错及用户管理
    ftp服务常见报错530报错认证失败(密码错误或者服务端拒绝)550服务本身未开启553文件系统不可写(权限问题)500服 ... [详细]
  • Pycharm配置文档教程
    1桌面找到快捷方式双击打开234需要自行注册5看自己喜欢选择喜欢白色选择左边喜欢黑色选择右边67可选如果你对Markdown感兴趣;或者会用就点击install不敢兴趣调到步骤88 ... [详细]
  • 明明白白用Qt5.10编写FTP客户端
    使用Linux自带工具实现定时下载FTP文件(文末)前言自从Qt5删除了QFtp模块后,就没有了可方便使用的FTP类。根据官方的说法&# ... [详细]
author-avatar
玻璃里的鱼鱼
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有