工做中,常常要把windows的文件夾同步到linux上。xftp也能夠,sublime也有遠程上傳的插件,但沒找到支持增量的。。。大量時間花在找插件,裝環境。。。而後一怒之下,本身東拼西湊了一下。python
支持:上傳文件夾,和刪除遠程文件。linux
增量是用當前時間和上次上傳時間對比實現的。windows
cache.dat記錄每一個文件的上傳時間,必要的時候能夠刪除從新上傳python2.7
環境。python2.7socket
#coding=utf-8 #!/usr/bin/python import os import os.path import shutil import sys import string import fnmatch import pickle import time from ftplib import FTP import paramiko import socket from stat import S_ISDIR import _cffi_backend import logging logging.basicConfig() cachefilename="cache.dat" class SSHSession(object): def __init__(self,hostname,port,username='root',password=None,key_file=None): # # Accepts a file-like object (anything with a readlines() function) # in either dss_key or rsa_key with a private key. Since I don't # ever intend to leave a server open to a password auth. # self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((hostname,port)) print("connect ", hostname, port) self.t = paramiko.Transport(self.sock) self.t.start_client() # supposed to check for key in keys, but I don't much care right now to find the right notation if password is not None: self.t.auth_password(username,password,fallback=False) else: raise Exception('Must supply either key_file or password') self.sftp=paramiko.SFTPClient.from_transport(self.t) try: l = pickle.load(open(cachefilename)) except IOError: l = [] self.db = dict(l) def put(self,localfile,remotefile): # Copy localfile to remotefile, overwriting or creating as needed. remotefile = remotefile.replace('\\', '/') print("upload %s %s"%(localfile, remotefile)) try: self.sftp.put(localfile,remotefile) except Exception as e: print "put ", e def put_all(self,localpath,remotepath,ignore_list): self.mkdir_ifnotexists(remotepath) if os.path.exists(localpath): for root, dirs, files, in os.walk(localpath): for file in files: filename = os.path.join(root, file) if any(fnmatch.fnmatch(filename, pattern) for pattern in ignore_list): print 'Ignore', filename continue mtime = time.ctime(os.path.getmtime(filename)) if self.db.get(filename, None) != mtime: remotefile=os.path.join(remotepath,filename) self.mkdir_ifnotexists(os.path.dirname(remotefile)) self.put(filename, remotefile) self.db[filename] = mtime # delete files for filename, value in self.db.items(): if os.path.exists(filename) == False: remotefile=os.path.join(remotepath,filename) try: self.sftp.remove(remotefile) except Exception as e: print 'Delete',filename, e pickle.dump(self.db.items(), open(cachefilename, "w")) print("ok!!!") def mkdir_ifnotexists(self, remotedirectory): remotedirectory = remotedirectory.replace('\\', '/') print "mkdir_ifnotexists", remotedirectory try: self.sftp.chdir(remotedirectory) # Test if remote_path exists except IOError: self.mkdir_p(remotedirectory) def mkdir_p(self, remotedirectory): """Change to this directory, recursively making new folders if needed. Returns True if any folders were created.""" if remotedirectory == '/': # absolute path so change directory to root self.sftp.chdir('/') return if remotedirectory == '': # top-level relative directory must exist return try: self.sftp.chdir(remotedirectory) # sub-directory exists except IOError: dirname, basename = os.path.split(remotedirectory.rstrip('/')) self.mkdir_p(dirname) # make parent directories self.sftp.mkdir(basename) # sub-directory missing, so created it self.sftp.chdir(basename) print "mkdir", basename return True def iter_find_files(path, fnexp): for root, dirs, files, in os.walk(path): for filename in fnmatch.filter(files, fnexp): yield os.path.join(root, filename) def main(): host="10.10.XX.XX" user="root" password="123" port=22 localpath="./" remotepath="/data/server/remotefolder" ignore_list=['*svn/*','*.py'] xfer = SSHSession(host,port,user,password) xfer.put_all(localpath, remotepath, ignore_list) if __name__ == '__main__': main() os.system("pause")
使用時填寫下(遠程地址,端口,用戶,密碼,本地路徑,遠程路徑,以及過濾文件)svn