github:easy-copy

import os
import sys
import time
import paramiko as pm '''
host格式:
{
"ip":"127.0.0.1",
"port":22,
"username":"root",
"password":"123456",
"file":"filename"
}
dst为host列表 要求:
源主机需要部署sshpass、scp
本机需要python3.4及以上,以及安装paramiko库
各源主机及目的主机能互联互通,ssh安全连接过
''' # 默认运行配置:源
example_src = {
"ip": "10.112.98.132",
"port": 22,
"username": "root",
"password": "111",
"file": "/root/111.o"
} # 默认运行配置:目的,数组
example_dst = [
{
"ip": "10.112.98.134",
"port": 22,
"username": "root",
"password": "222",
"file": "/root/222.o"
},
{
"ip": "10.112.98.151",
"port": 22,
"username": "root",
"password": "333",
"file": "/root/333.o"
},
{
"ip": "10.112.96.67",
"port": 22,
"username": "root",
"password": "444",
"file": "/root/111.o"
}
] # 显示详细信息
# detail = False
detail = True def do_copy(src_host, src_ssh, src_md5, dst_host, srcfile, compress=True, force=False, packname=".tarxjb"):
print()
print("*****cp*****")
print()
dst_ssh = create_ssh(dst_host)
# dst_ssh.exec_command('ssh -o "StrictHostKeyChecking no" {name}@{ip}'.format(name=src_host["username"],ip=src_host["ip"]))
# 检查对方是否已存在相同名字文件
if check_exist(dst_ssh, dst_host["file"]):
# 存在相同,判断是否强制覆盖,不覆盖则自动备份
if detail:
print("res:exist a same name file")
if not force:
if detail:
print("res:do backup")
backup_file_cmd = "mv {file} {file}.x.backup".format(
file=dst_host["file"])
dst_ssh.exec_command(backup_file_cmd)
# 传输文件指令
scp_cmd = "sshpass -p {pw} scp -P {port} {sfile} {duser}@{dip}:{dfile}".format(
port=dst_host["port"], pw=dst_host["password"], sfile=srcfile+packname, duser=dst_host["username"], dip=dst_host["ip"], dfile=srcfile+packname)
sin, sout, serr = src_ssh.exec_command(scp_cmd)
if detail:
print(sout.read().decode())
else:
sout.read().decode()
if detail:
print("res:scp done")
dst_md5 = compu_md5(dst_ssh, srcfile+packname)
if dst_md5 is None:
# md5计算失败
if detail:
print("err:md5 failed")
del_pack(dst_ssh, srcfile+packname)
return False
if src_md5 != dst_md5:
# md5不同,需要撤回包
if detail:
print("err:md5 is not consist")
del_pack(dst_ssh, srcfile+packname)
return False
# input("ddd")
res = compu_tar(dst_ssh, file=srcfile, type="x",
compress=compress, packname=packname)
# input("ddd")
if detail:
print("res:dst tar success")
if not res:
# 解压失败,需要撤回包
if detail:
print("err:tar failed")
del_pack(dst_ssh, srcfile+packname)
return False
if detail:
print("res:file check success")
# 删除中间包
# input("ddd")
del_pack(dst_ssh, srcfile+packname)
if detail:
print("res:remove dst temp pack success")
# 修改文件名
# input("ddd")
mv_file_cmd = "mv {file1} {file2}".format(
file1=srcfile, file2=dst_host["file"])
dst_ssh.exec_command(mv_file_cmd)
if detail:
print("res:filename update success")
dst_ssh.close()
if detail:
print("ok: {file} done".format(file=dst_host["file"]))
return True def copy(src_host, dst, compress=True, force=False):
# 复制文件,一对多
# 获取于源ip的ssh链接
src_ssh = create_ssh(src_host)
# 确定压缩参数
gzip = ""
if compress:
gzip = "z"
# 判断文件是否存在
res = check_exist(src_ssh, src_host["file"])
if detail:
print("src file exist? "+str(res))
# 执行压缩、打包命令
packname = "." + str(int(time.time())) + ".tarxjb"
res = compu_tar(src_ssh, src_host["file"],
"c", compress=compress, packname=packname)
if detail:
print("res:tar success? "+str(res))
# 计算原文件md5值
src_md5 = compu_md5(src_ssh, src_host["file"]+packname)
if detail:
print("src md5 :"+str(src_md5))
# 执行复制操作
res_cp = []
for row in dst:
res_cp.append({row["file"]: do_copy(
src_host, src_ssh, srcfile=src_host["file"], src_md5=src_md5, dst_host=row, packname=packname)})
# 删除本地临时文件
# input("ddd")
del_pack(src_ssh, src_host["file"]+packname)
if detail:
print("res:remove src temp pack success")
print()
print("*****res*****")
for index in res_cp:
print(index)
print("*****res*****")
print()
print("ok: all done!")
src_ssh.close() def del_pack(ssh, file):
# 删除中间包
del_cmd = "rm -f {file}".format(file=file)
sin, sout, serr = ssh.exec_command(del_cmd)
if detail:
print("cmd: rm "+sout.read().decode()) def create_ssh(host):
# 创建ssh链接
ssh = pm.SSHClient()
ssh.set_missing_host_key_policy(pm.AutoAddPolicy())
ssh.connect(hostname=host["ip"], port=host["port"],
username=host["username"], password=host["password"])
return ssh def compu_tar(ssh, file, type="c", compress=True, packname=".tarxjb"):
# 打包及解包
# gzip表示是否要用gzip压缩,默认压缩
gzip = ""
if compress:
gzip = "z"
# 打包指令
tar_cmd = "tar c{gzip}vfpP {file}{packname} {file} 2>/dev/null".format(
gzip=gzip, file=file, packname=packname)
# 解包指令
if type == "x":
tar_cmd = "tar x{gzip}vfpP {file}{packname} 2>/dev/null".format(
gzip=gzip, file=file, packname=packname)
if detail:
print("cmd: tar: " + tar_cmd)
stdin, stdout, stderr = ssh.exec_command(tar_cmd)
res = stdout.read().decode()
if res == "":
if detail:
print("err: {file}{packname} tar failed".format(
file=file, packname=packname))
return False
return True def check_exist(ssh, file):
# 检查文件是否存在
exist_cmd = "find {file} 2>/dev/null".format(file=file)
stdin, stdout, stderr = ssh.exec_command(exist_cmd)
res = stdout.read().decode()
if res == "":
if detail:
print("res: {file} is not exist".format(file=file))
return False
else:
if detail:
print("res: {file} is exist".format(file=file))
return True def compu_md5(ssh, file):
# 计算文件md5
src_md5_cmd = "md5sum {file} 2>/dev/null | awk \'{{print $1}}\'".format(
file=file)
stdin, stdout, stderr = ssh.exec_command(src_md5_cmd)
src_md5 = stdout.read().decode()
if detail:
print("cmd: md5 :"+src_md5_cmd)
print("res: cmd md5 res : "+src_md5)
if src_md5 == "":
if detail:
print("err: {file} md5 or tar failed".format(file=file))
src_md5 = None
else:
if detail:
print("res: {file} md5 : {md5}".format(file=file, md5=src_md5))
return src_md5 if __name__ == "__main__":
print("easy tar tool")
copy(example_src, example_dst, compress=True)

easy-copy服务器文件拷贝简易小工具的更多相关文章

  1. scp文件拷贝简易使用

    scp远程复制 属性变化 需要复制所属关系需要用-p选项 源目录复制之后目的目录的属性: srcdrwxr-xr-x. 2 root root 6 9月 4 16:28 2.txt dstdrwxr- ...

  2. BAT实现服务器文件同步

    服务器文件同步有很多工具,例如 GoodSync.rsync.BitTorrent Sync等……其实WINDOWS下自带了一个文件同步利器:ROBOCOPY.它是一个命令行的目录复制命令,自从Win ...

  3. web:频繁刷新浏览器的页面【小工具】

    [目的] 频繁刷新某一浏览器页面,小测试一下加载性能,或者打开的文件是否及时关闭,会不会导致服务器奔溃 [小工具] 新建txt,输入以下内容,并保存为html的格式,然后在浏览器中打开,则会定时刷新指 ...

  4. Python趣味实用小工具

    代码地址如下:http://www.demodashi.com/demo/12918.html python 趣味实用小工具 概述 用python实现的三个趣味实用小工具: 图片转Execl工具 , ...

  5. wordpress主题之后台菜单编辑,小工具

    1一:菜单编辑 在functions.php 文件加入 if (function_exists('register_nav_menus')) { register_nav_menus(array( / ...

  6. WPF做的迁移文件小工具

    客户这边需要往服务器上传PDF文件.然后PDF文件很多,需要挑出来的PDF文件也不少.因此做了个小工具. 功能很简单,选定源文件夹,选定记录着要提取的文件的excel 文件.OK ,界面如下. XAM ...

  7. 自己动手写一个U盘拷贝小工具

    这是五一期间,参照知乎上一篇的文章<十行代码--用python写一个USB病毒>写成的,最初只是单纯的想写成死循环,直到文件占满硬盘为止,第一个遇到的问题是,拷贝到硬盘之后,由于要无限次拷 ...

  8. 两台linux服务器相互拷贝文件的两个方法

    scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的.可能会稍微影响一下速度.当你服务器 ...

  9. WPF根据Oracle数据库的表,生成CS文件小工具

    开发小工具的原因: 1.我们公司的开发是客户端用C#,服务端用Java,前后台在通讯交互的时候,会用到Oracle数据库的字段,因为服务器端有公司总经理开发的一个根据Oracle数据库的表生成的cla ...

随机推荐

  1. CentOS7设置开机自启动方式

    方式一: # 在/etc/rc.d/rc.local文件中追加启动命令,该文件追加后,会随着机器自动后,自动运行文件中的命令 # vim /etc/rc.d/rc.local # 权限问题:在cent ...

  2. python线程类的start()和run()

    start()方法: 开始线程活动. 对每一个线程对象来说它只能被调用一次,它安排对象在一个另外的单独线程中调用run()方法,而非当前所处的线程,当该方法在同一个线程对象中被调用超过一次时,会引入R ...

  3. 对CNN 的理解

    CNN 的强大之处在于它的多层结构能自动学习特征,并且可以学习到多个层次的特征:较浅的卷积层感知域较小,学习到一些局部区域的特征. 较深的卷积层具有较大的感知域,能够学习到更加抽象一些的特征.这些抽象 ...

  4. 批量文件B中选出部分文件(与A文件夹数量相同),放到C中

    import glob import os,sys import shutil fileDir = 'F:/project/Breast/InBreast/INBreast/outimgpatch/n ...

  5. Docker 简单发布dotnet core项目 图文版

    原文:https://www.cnblogs.com/chuankang/p/9474591.html docker发布dotnet core简单流程 需要结合这个版本看哈 地址:https://ww ...

  6. 从项目中理解let和const为什么如此重要

    变量声明 变量声明方式 伴随js诞生的var // 语法 var varName = value var a = 1 // 这样子你就得到了一个变量 var缺陷场景分析 var specialUser ...

  7. MySQL实战45讲学习笔记:第四十四讲

    一.引子 这是我们专栏的最后一篇答疑文章,今天我们来说说一些好问题. 在我看来,能够帮我们扩展一个逻辑的边界的问题,就是好问题.因为通过解决这样的问题,能够加深我们对这个逻辑的理解,或者帮我们关联到另 ...

  8. tensor 中mul_,add_解读

    pytorch 中文网文档链接 https://ptorch.com/docs/1/Tensor 每一个张量tensor都有一个相应的torch.Storage保存其数据,张量类提供了一个多维的,横向 ...

  9. JMS简介与入门

    1:JMS引入 如果手机只能进行实时通话,没有留言和短信功能会怎么样?一个电话打过来,正好没有来得及接上,那么这个电话要传递的信息肯定就收不到了.为什么不能先将信息存下来,当用户需要查看信息的时候再去 ...

  10. idea中的后缀补全

    IDEA有个很牛逼的功能,那就是后缀补全(Postfix Completion),这个功能可以通过后缀来使用代码补全进行模板式地补全语句,如遍历循环语句(for.foreach).使用 String. ...