功能介绍
写个python脚本,对某文件夹进行监视,查看是否有文件/文件夹新建、删除、移动、更改,对不同的操作进行不同的处理,对于新产生的文件,监视到之后通过sftp协议立刻上传到服务器。
前期准备工作
配置sftp服务器
通过使用freesshd 软件轻松配置sftp服务器,关于具体配置看以下博客
freesshd安装使用教程 windows下安装sftp
相应的python库
watchdog
os
stat
paramiko
traceback
具体实现
实现主要是分为两个模块,监视文件夹,实现上传。
python:对文件夹进行监视
# coding=gbk
from watchdog.observers import Observer
from watchdog.events import *
import time
from upload import SSH # upload 为上传的python文件名
import time
class FileEventHandler(FileSystemEventHandler):
def __init__(self):
FileSystemEventHandler.__init__(self)
def on_moved(self, event):
if event.is_directory:
print("directory moved from {0} to {1}".format(event.src_path,event.dest_path))
else:
print("file moved from {0} to {1}".format(event.src_path,event.dest_path))
def on_created(self, event):
if event.is_directory:
print("directory created:{0}".format(event.src_path))
else:
print("file created:{0}".format(event.src_path))
a=str(event.src_path)
#time.sleep(20)
ssh = SSH(ip='xxx.xxx.xxx.xxx', username='root', password='1111') # 创建一个ssh类对象
ssh.connect() # 连接远程服务器
# ssh.sftp_put_dir('C:\MyFile\Pictures\share\\') # 上传整个文件夹
ssh.sftp_put_singleFile(a) #仅仅上传该单个文件
ssh.close()
def on_deleted(self, event):
if event.is_directory:
print("directory deleted:{0}".format(event.src_path))
else:
print("file deleted:{0}".format(event.src_path))
def on_modified(self, event):
if event.is_directory:
print("directory modified:{0}".format(event.src_path))
else:
print("file modified:{0}".format(event.src_path))
if __name__ == "__main__":
observer = Observer()
event_handler = FileEventHandler()
observer.schedule(event_handler,"C:\MyFile\Pictures\share",True) #监视的文件夹地址
observer.start() 开始监视
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
python :上传文件到服务器
# coding=gbk
import os
import stat
import paramiko
import traceback
class SSH(object):
def __init__(self,ip, port=22, username=None, password=None, timeout=30):
self.ip = ip
self.port = port
self.username = username
self.password = password
self.timeout = timeout
self.ssh = paramiko.SSHClient()
self.t = paramiko.Transport(sock=(self.ip, self.port))
def _password_connect(self):
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.ssh.connect(hostname=self.ip, port=22, username=self.username, password=self.password)
self.t.connect(username=self.username, password=self.password) # sptf 远程传输的连接
def _key_connect(self):
# 建立连接
self.pkey = paramiko.RSAKey.from_private_key_file('/id', )
# self.ssh.load_system_host_keys()
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.ssh.connect(hostname=self.ip, port=22, username=self.username, pkey=self.pkey)
self.t.connect(username=self.username, pkey=self.pkey)
def connect(self):
try:
self._key_connect()
except:
print('ssh key connect failed, trying to password connect...')
try:
self._password_connect()
except:
print('ssh password connect faild!')
def close(self):
self.t.close()
self.ssh.close()
def execute_cmd(self, cmd):
stdin, stdout, stderr = self.ssh.exec_command(cmd)
res, err = stdout.read(), stderr.read()
result = res if res else err
return result.decode()
# 从远程服务器获取文件到本地
def _sftp_get(self, remotefile, localfile):
sftp = paramiko.SFTPClient.from_transport(self.t)
sftp.get(remotefile, localfile)
# 从本地上传文件到远程服务器
def _sftp_put(self, localfile, remotefile):
sftp = paramiko.SFTPClient.from_transport(self.t)
sftp.put(localfile, remotefile)
# 递归遍历远程服务器指定目录下的所有文件
def _get_all_files_in_remote_dir(self, sftp, remote_dir):
all_files = list()
if remote_dir[-1] == '/':
remote_dir = remote_dir[0:-1]
files = sftp.listdir_attr(remote_dir)
for file in files:
filename = remote_dir + '/' + file.filename
if stat.S_ISDIR(file.st_mode): # 如果是文件夹的话递归处理
all_files.extend(self._get_all_files_in_remote_dir(sftp, filename))
else:
all_files.append(filename)
return all_files
def sftp_get_dir(self, remote_dir, local_dir):
try:
sftp = paramiko.SFTPClient.from_transport(self.t)
all_files = self._get_all_files_in_remote_dir(sftp, remote_dir)
for file in all_files:
local_filename = file.replace(remote_dir, local_dir)
local_filepath = os.path.dirname(local_filename)
if not os.path.exists(local_filepath):
os.makedirs(local_filepath)
sftp.get(file, local_filename)
except:
print('ssh get dir from master failed.')
print(traceback.format_exc())
# 递归遍历本地服务器指定目录下的所有文件
def _get_all_files_in_local_dir(self, local_dir):
all_files = list()
print(local_dir+"\nbegin")
for root, dirs, files in os.walk(local_dir, topdown=True):
for file in files:
print( file )
all_files.append(file)
# filename = os.path.join(root, file)
# all_files.append(filename)
# print(filename)
return all_files
def sftp_put_dir(self, local_dir):
try:
sftp = paramiko.SFTPClient.from_transport(self.t)
'''
if remote_dir[-1] == "/":
remote_dir = remote_dir[0:-1]
print(remote_dir)
'''
all_files = self._get_all_files_in_local_dir(local_dir)
for file in all_files:
'''
remote_filename = file.replace(local_dir, remote_dir)
remote_path = os.path.dirname(remote_filename)
print(remote_path)
try:
sftp.stat(remote_path)
except:
# os.popen('mkdir -p %s' % remote_path)
self.execute_cmd('mkdir -p %s' % remote_path) # 使用这个远程执行命令
'''
sftp.put(local_dir+file, '/'+file)
print("end put")
except:
print('ssh get dir from master failed.')
print(traceback.format_exc())
#上传单个文件
def sftp_put_singleFile(self, local_dir):
try:
sftp = paramiko.SFTPClient.from_transport(self.t)
filename=local_dir.split('\\')[-1]
sftp.put(local_dir, '/'+filename)
print("end put one file")
except:
print('ssh get dir from master failed.')
print(traceback.format_exc())
def sftp_put_dir2(self, local_dir):
try:
sftp = paramiko.SFTPClient.from_transport(self.t)
filename=local_dir.split("/")[-1]
print(filename)
sftp.put(local_dir, '/'+filename)
print("end put")
except:
print('ssh get dir from master failed.')
print(traceback.format_exc())
if __name__ == "__main__":
ssh = SSH(ip='121.36.23.121', username='root', password='1111') # 创建一个ssh类对象
ssh.connect() # 连接远程服务器
print("connect successful!")
# cmd = 'ls -lh'
# ssh.execute_cmd(cmd) # 执行命令
# remotefile, local_file = 'xxx', 'xxx'
# ssh.sftp_get(remotefile, local_file) # 下载文件
remotedir, localdir = '/', 'C:\MyFile\Pictures\share\\'
ssh.sftp_put_dir(localdir) # 上传文件夹
ssh.close()
总结
至此 完成,打开监视的python脚本即可,当文件新建,就会自动将新建的文件进行上传。