需求:由于有多个项目需要同步文件/目录,因为有多个项目(主机很多)用rsync直接拷贝不台方便。考虑直接遍历也比较慢。所以这里使用Python来封装rsync。
话不多说,直接上思路:
理解Rsync(关于Rsync自己去了解一下吧。。。):
本地拷贝 rsync -av 源目录/文件 目标目录/文件
远程拷贝 rsync -av 源目录/文件 用户@主机:/目录
1.定义个列表嵌套字典主要用来存主机信息;
2.定义个函数实现传入源目录和目标目录;
3.用多进程去执行这个函数。
直接上个效果图:
写的比较简单哈直接上代码
#!/usr/bin/python3
#__auther__: lshu
#__time__:20200809
import os ##主要用来调用shell命令
import sys ##实现传参sys.argv是一个列表。argparse也可以实现
import multiprocessing
import time
from colorama import init, Fore, Back, Style ##颜色库
##定义一个颜色类
class Colored(object):
def red(self, s):
return Fore.RED + s + Fore.RESET
def green(self, s):
return Fore.GREEN + s + Fore.RESET
def yellow(self, s):
return Fore.YELLOW + s + Fore.RESET
class RsyncObj(Colored): ##继承颜色类
def __init__(self):
##因为这里每个项目用的key是一样的所以直接定义主机了。key和用户直接定义变量了
self.ip_list = ["172.17.23.83","172.17.23.84","172.17.23.82"] ##目标主机
self.time_start = time.time() ##获取当前时间主要用来计算程序运行时间
self.key = "/app/hostkey/node.pem" #这里换成自己的key即可
self.user = "root" ##y用户
def rsync_task(self,ip):
ssh_comm = 'ssh -i {0}'.format(self.key) ##rsync -e 调用shell命令因为我们要用key登录所以需要这样定义
cmd = "rsync -avr -e '{0}' {1} {2}@{3}:{4}".format(ssh_comm,sys.argv[1],self.user,ip,sys.argv[2]) ##命令的封装 源为第一个参数,目标为第二个参数
try:
cmd = [x.strip('\n') for x in os.popen(cmd).readlines()] ##把输出结果的空行给去掉
cmd.insert(0,Colored.yellow(self,"---------------{}---------------".format(ip))) ##在列表最前面加个ip并设置颜色为黄色
#cmd[3] = cmd[-1]
for x in cmd: ##遍历打印结果
print (x)
except Exception as e:
print (Colored.red(self,e))
##主函数
def main(self):
po = multiprocessing.Pool(len(self.ip_list)) ##根据ip来个数来创建进程池
for ip in self.ip_list:
try:
po.apply_async(self.rsync_task,(ip,)) ##是用异步的方式来执行任务
except Exception as e:
print (Colored.red(self,e))
print (Colored.green(self,"---------------start---------------\
\n---------------start {} processes--------------- ".format(len(self.ip_list))))
po.close()
po.join() ##非阻塞。某一个进程正在拷贝的时候。另一个立即执行
print (Colored.green(self,"---------------end---------------\
\n---------------TimeUsed:{}---------------".format(time.time() - self.time_start))) ##打印输出
##入口
if __name__ == '__main__':
my = RsyncObj()
my.main()