运行环境:
本地:Window7 64位,Python 2.7.6,paramiko 1.12.1
远端:RedHat Linux, Ubuntu 14.04
# coding:utf8
import os
import sys
import time
import paramiko
import logging
def svnFilter(file_path):
if '.svn' in file_path:
return False
return True
def gitFilter(file_path):
if '.git' in file_path:
return False
return True
def settingFilter(file_path):
if '.setting' in file_path:
return False
return True
class SSHFileUpload:
"""docstring for SSHFileUpload"""
def __init__(self, hostname, port, username, password):
self.hostname = hostname
self.port = port
self.username = username
self.password = password
# self._candidate_dirs = []
self.__ssh = None
self._transport = None
self._sftp = None
def connect(self):
self.close()
self.__ssh_connect()
self._sftp = self.__ssh.open_sftp()
def reconnect(self):
self.connect()
logging.info("SSH session reconnected")
def is_connected(self):
transport = self.__ssh.get_transport() if self.__ssh else None
return transport and transport.is_active()
def __ssh_connect(self):
if (not self.__ssh):
self.__ssh = paramiko.SSHClient()
self.__ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.__ssh.connect(self.hostname, self.port, self.username, self.password)
self._transport = self.__ssh.get_transport()
def __ssh_exec(self, command):
sin, sout, serr = self.__ssh.exec_command(command)
logging.info("SSH exec_command: %s ", command)
# if sout.readlines():
# logging.info('stdout: %s', sout.readlines())
# if serr.readlines():
# logging.info('stderr: %s', serr.readlines())
# raise SystemExit
# sys.exit(1)
# return sin, sout, serr
def exec_command(self, command):
if not self.is_connected():
self.reconnect()
return self.__ssh_exec(command)
def invoke_shell(self, command='', password='abc123!@#'):
channel = self.__ssh.invoke_shell()
return channel
def __ssh_close(self):
if (self.__ssh):
self.__ssh.close()
def closeTransport(self):
if self._transport and self._transport.is_active():
self._transport.close()
def closeSFTP(self):
if self._sftp:
self._sftp.close()
def close(self):
self.closeTransport()
self.closeSFTP()
self.__ssh_close()
def run(self):
pass
def copyFile(self, local_path, remote_path):
if not self.is_connected():
self.reconnect()
try:
self._sftp.put(local_path, remote_path)
except Exception, e:
r_dir = os.path.split(remote_path)[0]
cmd = "mkdir -p %s" % r_dir
self.__ssh_exec(cmd)
time.sleep(0.5)
self._sftp.put(local_path, remote_path)
logging.info("copy [%s] to remote [%s]", local_path, remote_path)
def copyDir(self, local_dir, remote_dir, filters=[gitFilter, svnFilter, settingFilter]):
logging.info("Coping [%s] to [%s]\n" % (local_dir, remote_dir))
candidate_dirs = self._walkLocalDirs(local_dir)
candidate_dirs = self.__doFilters(candidate_dirs, filters)
local_dir = local_dir.replace('\\', '/')
for i, candidate_path in enumerate(candidate_dirs):
local_file = candidate_dirs[i]
remote_file = candidate_dirs[i].replace(local_dir, remote_dir).replace('\\', '/').replace('//', '/')
# print local_file, " : ", remote_file
remote_file = unicode(remote_file, 'cp936').encode('utf8')
self.copyFile(local_file, remote_file)
logging.info("Copied [%s] to [%s]\n" % (local_dir, remote_dir))
def doUpload(self, local_dir, remote_dir, filters=[]):
candidate_dirs = self._walkLocalDirs(local_dir)
candidate_dirs = self.__doFilters(candidate_dirs, filters)
local_dir = os.path.split(local_dir)[0].replace('\\', '/')
for i, candidate_path in enumerate(candidate_dirs):
local_file = candidate_dirs[i]
remote_file = candidate_dirs[i].replace(local_dir, remote_dir).replace('\\', '/').replace('//', '/')
try:
self._sftp.put(local_file, remote_file)
except Exception, e:
r_dir = os.path.split(remote_file)[0]
cmd = "mkdir -p %s" % r_dir
self.__ssh_exec(cmd)
time.sleep(0.5)
self._sftp.put(local_file, remote_file)
# print e
logging.info("upload [%s] to remote [%s]", local_file, remote_file)
def _walkLocalDirs(self, local_dir):
''' Get all file path in local_dir and RETURN _candidate_dirs list'''
_candidate_dirs = []
if os.path.isfile(local_dir):
_candidate_dirs.append(local_dir.replace('\\', '/'))
return _candidate_dirs
for dir_name, sub_dirs, files in os.walk(local_dir):
dir_name = dir_name.replace('\\', '/')
for filename in files:
_candidate_dirs.append(dir_name + '/' + filename)
return _candidate_dirs
def __doFilters(self, candidate_dirs, filters=[]):
for func in filters:
candidate_dirs = filter(func, candidate_dirs)
return candidate_dirs
hostname='your_ip'
username='test'
password='test'
port=22
if __name__ == '__main__':
local_dir = r'E:/workspace/static/images'
remote_dir = "temp/aaa"
sfu = SSHFileUpload(hostname, port, username, password)
# Test
# sfu.run()
sfu.connect()
sfu.copyDir(local_dir, remote_dir)
local_dir = r'E:/workspace/static/images'
remote_dir = "temp/bbb"
sfu.doUpload(local_dir, remote_dir, filters=[svnFilter, vipFilter])
sfu.close()