ssh备份策略
import datetime
import os
import re
import time
import win32gui
import paramiko # 导入paramiko
import pyautogui
import pymysql
import pyperclip
import win32con
db = pymysql.connect(host='localhost', port=3306, user='root', password='123456', database='filetime',
charset='utf8mb4')
cursor = db.cursor()
def insert_data(path, time):
# 如果数据库不存在文件,则创建一条记录包括文件绝对路径和修改时间
ins = 'insert into file (path, modifytime) values (%s, %s)'
cursor.execute(ins, (path, time))
db.commit()
# cursor.close()
# db.close()
def text(word):
# 写入修改事件
ins = 'insert into text (content) values (%s)'
cursor.execute(ins, "file_move事件" + word)
db.commit()
# cursor.close()
# db.close()
def select_data():
# 查询file表文件名修改时间
sql = 'select path, modifytime from file '
# print(sql)
sql = cursor.execute(sql)
# print(sql)
all_data = cursor.fetchmany(sql) # 查询的个数
print(all_data)
# for i in all_data:
# print(i[0], i[1])
return all_data
def sql_update(path, modifytime):
# 修改数据库file表的修改过文件时间名字的时间
try:
ins = 'UPDATE file SET modifytime = "{}" WHERE path = %s'.format(modifytime)
print(ins, path)
cursor.execute(ins, path)
db.commit()
# print(ins)
# cursor.close()
# db.close()
except Exception as result:
print("sql_update错误", result)
def ssh_file_manage(cmdList):
# ssh命令:第一种ssh连接执行指令方式,把文件发送到centos上,并修改数据库文件时间
transport = paramiko.Transport((hostname, port))
transport.connect(username=username, password=password)
sftp = paramiko.SFTPClient.from_transport(transport)
# 遍历cmd列表里面文件一个一个上传
for index, filepath, filename, filetime in cmdList:
filepath = filepath.replace("\\", "/")
print(filepath, filename, linux_path + filepath+filename)
try:
sftp.put(win_path + filepath+filename, linux_path + filepath+filename)
# sftp.get('/home/blog/media' + cmd, 'C:/Users/yys53/OneDrive/python/blog/media' + cmd)
if index == 0:
insert_data(filepath+filename, filetime)
elif index == 1:
sql_update(filepath+filename, filetime) # 修改时间
text('把win10文件:C:/Users/yys53/OneDrive/python' + filepath+filename + linux_path + filepath+filename)
if filepath:
print("py文件更新需要reload")
reload.append(filepath)
except FileNotFoundError:
mkdir_list.append("mkdir -p %s" % linux_path+filepath)
transport.close()
def ssh_console(cmdList):
# ssh命令:如果不存在文件夹用ssh来新建,还用执行reload
try:
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 创建ssh连接
client.connect(hostname=hostname, port=port, username=username, password=password)
# 开启ssh管道
ssh = client.get_transport().open_session()
ssh.get_pty()
ssh.invoke_shell()
for cmd in cmdList:
# 远程主机需要有这个py文件
ssh.sendall(cmd + " \n")
time.sleep(0.5) # 等待多少秒远程的遍历完
result = ssh.recv(302400) # 显示多少字
# print(result)
result = result.decode("utf-8")
print("结果", result)
except Exception as e:
print("[%s] %s 目标失败,原因是 %s" % (datetime.datetime.now(), hostname, str(e)))
else:
pass
# print("[%s] %s 目标成功" % (datetime.datetime.now(), hostname))
finally:
ssh.close()
client.close()
def compare_tme():
data = select_data()
for i in half_file_list:
# print(win_path+i)
for root, dirs, files in os.walk(win_path + i):
# (win_path + '\\blog\\' + iroots)代表需要遍历的根文件夹
# root表示正在遍历的文件夹的名字(根 / 子)
# dirs记录正在遍历的文件夹下的子文件夹集合
# files记录正在遍历的文件夹中的文件集合
for file in files:
# print(root[-1])
if root[-1] == '\\':
pass
else:
root = root + "\\"
# print(r_list)
f = root + file
mtime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(os.path.getmtime(f))) # 修改时间
filepath = root[len(win_path):].replace("\\", "/") # 获取后缀不同的地方得到文件路径,不包括文件名
for i in data:
# i[0]为数据库一半路径+文件名,i[1]为最后修改时间
# 判断文件夹匹配
if filepath + file == i[0]:
# print(r_list[0] + file, i[0])
# 如果文件夹相等,比一下时间
if i[1] == mtime:
pass
# print("满足")
else:
print("时间不满足%s,当前时间%s,最近修改时间%s" % (filepath + file, i[1], mtime))
# 不满足做的事
# 1.移动文件
filepath_time_list.append((1, filepath, file, mtime))
print(filepath)
time.sleep(0.5)
break
else:
print("没有此文件:%s,需要插入file表中" % filepath + file)
# # 插入file表
filepath_time_list.append((0, filepath, file, mtime))
# print("文件路径:%s, 最新修改 : %s" % (file_dir, mtime))
if __name__ == '__main__':
filepath_time_list = []
mkdir_list = []
reload = []
win_path = 'C:\\Users\\yys53\\OneDrive\\python\\blog'
linux_path = "/home/blog"
hostname =ip
username = ""
password = ""
port = 22
# 需要同步blog下的文件相对路径
half_file_list = ["\\blog\\", '\\home\\', '\\templates\\', '\\static\\', '\\diary\\', '\\users\\']
compare_tme()
print(filepath_time_list)
if len(filepath_time_list) > 0:
# 获取所有需要上传列表相对路径,一次性上传完
ssh_file_manage(filepath_time_list)
if mkdir_list:
print("有文件夹不存在需要创建")
print(list(set(mkdir_list)))
cmdList = []
ssh_console(list(set(mkdir_list)))
# 创建之后再移动文件
filepath_time_list = []
compare_tme()
print(filepath_time_list)
if len(filepath_time_list) > 0:
# 获取所有需要上传列表相对路径,一次性上传完
ssh_file_manage(filepath_time_list)
if reload:
print("有文件上传CentOs需要重启supervisor")
ssh_console(['supervisorctl reload'])
在远程新建一个file.py文件获取文件路径和时间
import time
import os
path = "/home/blog/media"
len_p = len(path)
lis = []
for root, dirs, files in os.walk(path):
for file in files:
print(root)
if root[-1] == '/':
pass
else:
root = root + "/"
f = root + file
# print(f)
mtime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(os.path.getmtime(f)))
lis.append((root[len_p:], file ,mtime))
print(lis)
也可以根据md5,但是比较慢
def get_file_md5(md5_path):
d5 = hashlib.md5()
with open(md5_path, 'rb') as f:
while True:
data = f.read(2024)
if not data:
break
d5.update(data) # update添加时会进行计算
return d5.hexdigest()
本地计算机获取文件内容
import datetime
import os
import time
import paramiko # 导入paramiko
import pymysql
db = pymysql.connect(host='localhost', port=3306, user='root', password='123456', database='filetime',
charset='utf8mb4')
cursor = db.cursor()
def insert_data(path, file_time):
ins = 'insert into getfile(path,time) values (%s, %s)'
cursor.execute(ins, (path, file_time))
db.commit()
def sql_update(path, modifytime):
# 修改数据库file表的修改过文件时间名字的时间
try:
ins = 'UPDATE getfile SET time = "{}" WHERE path = %s'.format(modifytime)
cursor.execute(ins, path)
db.commit()
# cursor.close()
# db.close()
except Exception as result:
print("sql_update错误", result)
def text(word):
ins = 'insert into text (content) values (%s)'
cursor.execute(ins, "file_get事件" + word)
db.commit()
def select_data():
sql = 'select path, time from getfile '
# print(sql)
sql = cursor.execute(sql)
# print(sql)
all_data = cursor.fetchmany(sql) # 查询的个数
# print(all_data)
# for i in all_data:
# print(i[0], i[1])
return all_data
def sshRunCmd(hostname, username, password, cmdList):
try:
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 创建ssh连接
client.connect(hostname=hostname, port=22, username=username, password=password)
# 开启ssh管道
ssh = client.get_transport().open_session()
ssh.get_pty()
ssh.invoke_shell()
# 执行指令
sq_all_data = select_data()
for cmd in cmdList:
# 带个\n相当于回车
ssh.sendall(cmd + " \n")
# 如果读取很多文件改下time.sleep和recv的值,如果获取md5要改成3秒60万左右
time.sleep(1) # 等待多少秒远程的遍历完
result = ssh.recv(302400) # 显示多少字
# print(result)
result = result.decode("utf-8")
# print(result)
import re
re_lis = re.compile("(\\[\\(.*?\\)\\])", re.S).findall(result)
# print(re_lis[0])
for path, filename, file_time in eval(re_lis[0]):
# print(i[0], i[1])
for j in sq_all_data:
sq_file = j[0]
sq_time = j[1]
if sq_file == path+filename:
if sq_time == file_time:
pass
# print("满足")
break
else:
print("时间不满足:" + path+filename)
lis.append((1, path+filename, file_time))
break
else:
print("文件不存在:" + path+filename)
if not os.path.exists(pc_file + path):
# 递归创建文件
os.makedirs(pc_file + path)
print("文件夹不存在,需要创建")
else:
pass
# print("文件夹存在,不需创建")
lis.append((0, path+filename, file_time))
except Exception as e:
print("[%s] %s 目标失败,原因是 %s" % (datetime.datetime.now(), hostname, str(e)))
else:
pass
# print("[%s] %s 目标成功" % (datetime.datetime.now(), hostname))
finally:
ssh.close()
client.close()
def file_manage(cmdList):
if cmdList:
transport = paramiko.Transport((hostname, port))
transport.connect(username=username, password=password)
sftp = paramiko.SFTPClient.from_transport(transport)
for index, filename, filetime in cmdList:
try:
sftp.get(linux_file + filename, pc_file + filename)
# 等于0时,文件不存在,需要插入数据,等于1时文件存在,时间需修改,需要更新数据
if index == 0:
insert_data(filename, filetime) # 数据都带\r所以加个
elif index == 1:
sql_update(filename, filetime)
text('把centos文件:' + linux_file + filename + '复制到 ' + pc_file + filename)
except Exception as e:
print("错误路径:%s,原因%s" % (index + filename + filename, e))
text("错误路径:%s,原因%s" % (index + filename + filename, e))
transport.close()
os.system('mysqldump yys -h 175.24.115.96 -u root -p519Yang982 | mysql yys -u root -p123456') # 复制数据库
if __name__ == '__main__':
hostname = ip
username = ""
password = ""
port = 22
lis = []
pc_file = "C:/Users/yys53/OneDrive/python/blog/media"
linux_file = '/home/blog/media'
# 远程主机需要有这个py文件
cmdList = ["python3 /home/blog/file.py"]
sshRunCmd(hostname, username, password, cmdList)
# select_data()
print(lis)
file_manage(lis)
判断远程和本地文件时间是否相等进行复制文件
create table backup(
id int unsigned primary key auto_increment not null,
path varchar(200),
modifytime varchar(20)
)charset=utf8mb4;
import datetime
import os
import time
import paramiko # 导入paramiko
import pymysql
db = pymysql.connect(host='localhost', port=3306, user='root', password='123456', database='filetime',
charset='utf8mb4')
cursor = db.cursor()
def insert_data(path, time):
# 如果数据库不存在文件,则创建一条记录包括文件绝对路径和修改时间
ins = 'insert into backup (path, modifytime) values (%s, %s)'
cursor.execute(ins, (path, time))
db.commit()
# cursor.close()
# db.close()
def text(word):
# 写入修改事件
ins = 'insert into text (content) values (%s)'
cursor.execute(ins, "file_move事件" + word)
db.commit()
# cursor.close()
# db.close()
def select_data():
# 查询file表文件名修改时间
sql = 'select path, modifytime from backup '
# print(sql)
sql = cursor.execute(sql)
# print(sql)
all_data = cursor.fetchmany(sql) # 查询的个数
print(all_data)
# for i in all_data:
# print(i[0], i[1])
return all_data
def sql_update(path, modifytime):
# 修改数据库file表的修改过文件时间名字的时间
try:
ins = 'UPDATE backup SET modifytime = "{}" WHERE path = %s'.format(modifytime)
print(ins, path)
cursor.execute(ins, path)
db.commit()
# print(ins)
# cursor.close()
# db.close()
except Exception as result:
print("sql_update错误", result)
def ssh_file_manage(cmdList):
# ssh命令:第一种ssh连接执行指令方式,把文件发送到centos上,并修改数据库文件时间
transport = paramiko.Transport((hostname, port))
transport.connect(username=username, password=password)
sftp = paramiko.SFTPClient.from_transport(transport)
# 遍历cmd列表里面文件一个一个上传
for index, filepath, filename, filetime in cmdList:
filepath = filepath.replace("\\", "/")
print(filepath, filename, linux_path + filepath + filename)
try:
sftp.put(win_path + filepath + filename, linux_path + filepath + filename)
# sftp.get('/home/blog/media' + cmd, 'C:/Users/yys53/OneDrive/python/blog/media' + cmd)
if index == 0:
insert_data(filepath + filename, filetime)
elif index == 1:
sql_update(filepath + filename, filetime) # 修改时间
text('把win10文件:C:/Users/yys53/OneDrive/python' + filepath + filename + linux_path + filepath + filename)
except FileNotFoundError:
mkdir_list.append("mkdir -p %s" % linux_path + filepath)
transport.close()
def ssh_console(cmdList):
# ssh命令:如果不存在文件夹用ssh来新建,还用执行reload
try:
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 创建ssh连接
client.connect(hostname=hostname, port=port, username=username, password=password)
# 开启ssh管道
ssh = client.get_transport().open_session()
ssh.get_pty()
ssh.invoke_shell()
for cmd in cmdList:
# 远程主机需要有这个py文件
ssh.sendall(cmd + " \n")
time.sleep(0.5) # 等待多少秒远程的遍历完
result = ssh.recv(302400) # 显示多少字
# print(result)
result = result.decode("utf-8")
print("结果", result)
except Exception as e:
print("[%s] %s 目标失败,原因是 %s" % (datetime.datetime.now(), hostname, str(e)))
else:
pass
# print("[%s] %s 目标成功" % (datetime.datetime.now(), hostname))
finally:
ssh.close()
client.close()
def compare_tme():
data = select_data()
for root, dirs, files in os.walk(win_path):
# (win_path + '\\blog\\' + iroots)代表需要遍历的根文件夹
# root表示正在遍历的文件夹的名字(根 / 子)
# dirs记录正在遍历的文件夹下的子文件夹集合
# files记录正在遍历的文件夹中的文件集合
for file in files:
# print(root[-1])
if root[-1] == '/':
pass
else:
root = root + "/"
# print(r_list)
f = root + file
mtime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(os.path.getmtime(f))) # 修改时间
filepath = root[len(win_path):].replace("\\", "/") # 获取后缀不同的地方得到文件路径,不包括文件名
for i in data:
# i[0]为数据库一半路径+文件名,i[1]为最后修改时间
# 判断文件夹匹配
if filepath + file == i[0]:
# print(r_list[0] + file, i[0])
# 如果文件夹相等,比一下时间
if i[1] == mtime:
pass
# print("满足")
else:
print("时间不满足%s,当前时间%s,最近修改时间%s" % (filepath + file, i[1], mtime))
# 不满足做的事
# 1.移动文件
filepath_time_list.append((1, filepath, file, mtime))
print(filepath)
time.sleep(0.5)
break
else:
print("没有此文件:%s,需要插入file表中" % filepath + file)
# # 插入file表
filepath_time_list.append((0, filepath, file, mtime))
# print("文件路径:%s, 最新修改 : %s" % (file_dir, mtime))
if __name__ == '__main__':
filepath_time_list = []
mkdir_list = []
win_path = 'G:/backup'
linux_path = "/home/yys/backup"
hostname = "192.168.31.133"
username = "yys"
password = "123456"
port = 22
# 需要同步blog下的文件相对路径
compare_tme()
print(filepath_time_list)
if len(filepath_time_list) > 0:
# 获取所有需要上传列表相对路径,一次性上传完
ssh_file_manage(filepath_time_list)
if mkdir_list:
print("有文件夹不存在需要创建")
print(list(set(mkdir_list)))
cmdList = []
ssh_console(list(set(mkdir_list)))
# 创建之后再移动文件
filepath_time_list = []
compare_tme()
print(filepath_time_list)
if len(filepath_time_list) > 0:
# 获取所有需要上传列表相对路径,一次性上传完
ssh_file_manage(filepath_time_list)
本文作者: 永生
本文链接: https://yys.zone/detail/?id=159
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
发表评论
评论列表 (0 条评论)
暂无评论,快来抢沙发吧!