利用Python3在Windows同步文件到Linux服务器(2)

修改了几个部分:

  1. 支持配置多台服务器,不配置端口号时,默认端口为22
  2. 支持按目录递归复制
  3. print函数不直接拼接字符串,改成了格式化字符串

 

递归复制的代码参考了一些网上的代码,其中

try:
    sftp.put(real_local_path, real_server_path)
except:
    sftp.mkdir(os.path.join(server_path, dirpath).replace("\\", "/"))
    sftp.put(real_local_path, real_server_path)

这段在很多示例中是先采用 mkdir 创建目录,捕捉到异常后pass,然后再复制文件。具体考虑到我的实际情况,是文件夹已经存在的情况比较多,所以采取首先尝试同步文件的策略。

由于是单线程,一条连接,所以在需要同步的文件多的情况下,效率还是个很大的问题。

修改后的源码:

#!-*- coding: utf-8 -*-
"""
练手小程序
"""
import json
import paramiko
import os


# 递归复制文件
def put_recursive(sftp, local_path, server_path):
    sync_file_count = 0
    local_path_split = os.path.split(local_path)
    os.chdir(local_path_split[0])
    local_path_parent = local_path_split[1]
    for (dirpath, dirnames, files) in os.walk(local_path_parent):
        for file in files:
            real_local_path = os.path.join(dirpath, file)
            real_server_path = os.path.join(server_path, dirpath, file).replace("\\", "/")
            try:
                sftp.put(real_local_path, real_server_path)
            except:
                sftp.mkdir(os.path.join(server_path, dirpath).replace("\\", "/"))
                sftp.put(real_local_path, real_server_path)
            print("已同步本地文件: '{}'  到服务器路径:'{}'".format(local_path_split[0] + real_local_path, real_server_path))
            sync_file_count += 1
    return sync_file_count


def main():
    default_port = 22
    global_sync_file_count = 0

    with open("config.json") as config_file:
        config = json.load(config_file)
    print("读取配置文件成功!")

    host_config = config["host_config"]
    for host in host_config:
        try:
            ip = host["ip"]
            port = host.get("port", default_port)
            username = host["username"]
            password = host["password"]
            path_list = host["path_list"]
            sync_file_count = 0
            print("开始连接远程服务器:{}".format(ip))

            transport = paramiko.Transport((ip, port))
            transport.connect(username=username, password=password)
            sftp = paramiko.SFTPClient.from_transport(transport)

            print("连接远程服务器 '{}' 成功!".format(ip))
            print("********同步文件到服务器 '{}' --开始".format(ip))
            for path in path_list:
                sync_file_count = put_recursive(sftp, path["local_path"], path["server_path"])
                global_sync_file_count += sync_file_count
            print("********同步文件到服务器 '{}' --结束,同步了 {} 个文件".format(ip, sync_file_count))
        except IOError:
            pass
        finally:
            sftp.close()
            transport.close()
            print("成功关闭与远程服务器'{}'的连接".format(ip))

    print("已经全部同步完成!一共同步了 {} 个文件!".format(global_sync_file_count))


if __name__ == '__main__':
    import time
    main()
    print("共用了", time.clock(), "秒")

 

配置文件:

{
  "host_config":[
    {
      "ip":"127.0.0.1",
      "port":666,
      "username":"root",
      "password":"root",
      "path_list":[
        {
          "local_path":"G:/Java",
          "server_path":"/home"
        }
      ]
    },
    {
      "ip":"127.0.0.1",
      "username":"root",
      "password":"root",
      "path_list":[
        {
          "local_path":"G:/uploadFile",
          "server_path":"/home"
        }
      ]
    }
  ]
}

 

转载于:https://my.oschina.net/u/1756290/blog/679226

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值