需求

项目需要定时移植多个客户服务器的文件到公司服务器上,确保文件定时同步和生成监控日志

机制原理

1.客户和公司服务器同时安装vpn,绕过复杂的网关,linux下使用的OpenVPN

2.服务器定时运行Python移植脚本

3.使用Python的原因,支持多线程和完善ftp类库

代码实现(Python)

Python脚本

# coding=utf-8
import os
import ftplib
import threading
import time
import pymysql # ftp操作类
class myFtp:
# 初始化类,连接生产服务器,链接mysql
def __init__(self, host, port, user, passwd, dbCursor): self.ftp = ftplib.FTP()
self.msgHost = host
self.dbCursor = dbCursor
self.user = user
self.passwd = passwd
self.filepath = '/'
try:
self.ftp.connect(host, port)
msgInsert(self.user, "info", "ftp连接成功", self.dbCursor)
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + " " + self.msgHost + " ftp连接成功")
except:
msgInsert(self.user, "error", "ftp连接失败", self.dbCursor)
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + " " + self.msgHost + " ftp连接失败") # ftp错误级别
self.ftp.set_debuglevel(0)
# self.ftp.set_pasv(0)
try:
self.ftp.login(user, passwd)
self.loginSuccess = 1
msgInsert(self.user, "info", "ftp用户登录成功", self.dbCursor)
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + " " + self.msgHost + " ftp用户登录成功") except:
self.loginSuccess = 0
msgInsert(self.user, "error", "ftp用户登录失败", self.dbCursor)
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + " " + self.msgHost + " ftp用户登录失败") # 检查ftp是否登录成功
def isLogin(self):
# return 1
return self.loginSuccess # 下载单个文件
def downLoadFile(self, LocalFile, RemoteFile):
curTime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
# 如果本地有文件删除
if os.path.exists(LocalFile):
os.remove(LocalFile)
# 如果本地写入
try:
buffer_size = 1024 * 1024
file_handler = open(LocalFile, 'wb')
self.ftp.retrbinary('RETR ' + RemoteFile, file_handler.write, buffer_size)
file_handler.close()
msgInsert(self.user, "info", LocalFile + "写入本地成功", self.dbCursor)
print(curTime + " " + self.msgHost + " " + LocalFile + "写入本地成功")
self.isFileSuccess = 1 except:
msgInsert(self.user, "error", LocalFile + "写入本地失败", self.dbCursor)
print(curTime + " " + self.msgHost + " " + LocalFile + "写入本地失败")
self.isFileSuccess = 0 # 删除ftp文件
if self.isFileSuccess == 1:
try:
self.ftp.delete(RemoteFile)
msgInsert(self.user, "info", self.filepath + RemoteFile + "删除ftp文件成功", self.dbCursor)
print(curTime + " " + self.msgHost + " " + self.filepath + RemoteFile + "删除ftp文件成功")
except:
msgInsert(self.user, "error", self.filepath + RemoteFile + "删除ftp文件失败", self.dbCursor)
print(curTime + " " + self.msgHost + " " + self.filepath + RemoteFile + "删除ftp文件失败") return True # 下载整个目录下的文件
def downLoadFileTree(self, LocalDir, RemoteDir):
if not os.path.exists(LocalDir):
curTime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
try:
os.makedirs(LocalDir)
msgInsert(self.user, "info", LocalDir + "本地目录创建成功", self.dbCursor)
except:
msgInsert(self.user, "error", LocalDir + "本地目录创建失败", self.dbCursor)
print(curTime + " " + self.msgHost + " " + LocalDir + "本地目录创建失败")
try:
curTime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
self.ftp.cwd(RemoteDir)
RemoteNames = self.ftp.nlst()
msgInsert(self.user, "info", self.filepath + "切换目录和读取列表成功", self.dbCursor)
print(curTime + " " + self.msgHost + " " + self.filepath + "切换目录和读取列表成功")
except:
msgInsert(self.user, "error", self.filepath + "切换目录和读取列表失败", self.dbCursor)
print(curTime + " " + self.msgHost + " " + self.filepath + "切换目录和读取列表失败") for file in RemoteNames:
Local = os.path.join(LocalDir, file)
# print(file)
if file.find(".") == -1:
self.filepath += file + '/'
if not os.path.exists(Local):
try:
os.makedirs(Local)
msgInsert(self.user, "info", Local + "本地目录创建成功", self.dbCursor)
print(curTime + " " + self.msgHost + " " + Local + "本地目录创建成功")
except:
msgInsert(self.user, "error", Local + "本地目录创建失败", self.dbCursor)
print(curTime + " " + self.msgHost + " " + Local + "本地目录创建失败") self.downLoadFileTree(Local, file)
# 删除目录
self.ftp.rmd(file)
elif file.find(".") == 0:
pass
else:
self.downLoadFile(Local, file)
self.ftp.cwd("..")
# print('start')
# print(self.filepath)
self.filepath = self.filepath[0:self.filepath.rstrip("/").rfind("/")+1]
# print(self.filepath)
# print('end')
return def close(self):
self.ftp.quit() # 移植函数
def getSiteFtpFile(host, port, username, passwd, localDir, dbconn):
# dbconn = sqlite3.connect('getFile.sqlite3', check_same_thread=False)
try:
dbconn = pymysql.connect("127.0.0.1", "root", "root", "ftpwork")
dbCursor = dbconn.cursor()
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + " " + host + " 连接mysql成功")
except:
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + " " + host + " 连接mysql失败") ftp = myFtp(host, port, username, passwd, dbCursor)
isLogin = ftp.isLogin()
if isLogin == 1:
try:
ftp.downLoadFileTree(localDir, '/')
except:
msgInsert(username, "error", "ftp.downLoadFileTree方法执行中断", dbCursor)
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + " " + host + " ftp.downLoadFileTree方法执行中断") ftp.close() print(time.strftime("########### " + "%Y-%m-%d %H:%M:%S", time.localtime()) + " " + host + " 执行完成 ###########")
# dbCursor.close()
dbconn.commit()
dbconn.close() # 自定义线程
class myThread(threading.Thread):
def __init__(self, threadID, name, host, port, username, passwd, localDir, dbConn):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.host = host
self.port = port
self.username = username
self.passwd = passwd
self.localDir = localDir
self.dbConn = dbConn def run(self):
print("开始线程:" + self.name)
getSiteFtpFile(self.host, self.port, self.username, self.passwd, self.localDir, self.dbConn)
print("退出线程:" + self.name) # 监控消息写入mysql
def msgInsert(msgHost, msgType, msgContent, dbCur):
datetime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
dbCur.execute("INSERT INTO ftp_getfile (title,content,w_time,msgtype) \
VALUES ('" + msgHost + "', '" + msgContent.replace("\\","/") + "','" + datetime + "' ,'" + msgType + "')") if __name__ == "__main__": conn = ''
# 创建两个线程
thread1 = myThread(1, "Thread-1", "ftp_ip", 21, 'ftp_user', 'ftp_passwd', 'Z:/', conn)
# thread2 = myThread(2, "Thread-2", "ftp_ip", 21, 'ftp_user', 'ftp_passwd', "Z:/", conn)
# thread3 = myThread(3, "Thread-3", "ftp_ip", 21, 'ftp_user', 'ftp_passwd', 'D:/root-python/test/03', conn)
# thread4 = myThread(4, "Thread-4", "ftp_ip", 82, 'ftp_user', 'ftp_passwd', 'D:/root-python/test/04', conn)
# thread5 = myThread(5, "Thread-5", "ftp_ip", 21, 'ftp_user', 'ftp_passwd', 'D:/root-python/test/05', conn)
# thread6 = myThread(6, "Thread-6", "ftp_ip", 82, 'ftp_user', 'ftp_passwd', 'D:/root-python/test/06', conn)
try:
# 开启新线程
thread1.start()
# thread2.start()
# thread3.start()
# thread4.start()
# thread5.start()
# thread6.start() thread1.join()
# thread2.join()
# thread3.join()
# thread4.join()
# thread5.join()
# thread6.join() except:
print("Error: unable to start thread") # while 1:
# pass

Python脚本通过ftp协议移植文件的更多相关文章

  1. 一个ftp协议传输文件之后执行脚本无法工作的情况

    作者:良知犹存 转载授权以及围观:欢迎添加微信号:Conscience_Remains 总述         移植一个文件系统时候,我在window下git clone了对方仓库源码,然后用FileZ ...

  2. vsftpd-基于ftp协议的文件传输服务器软件

    第一部分:在Linux上部署vsftpd服务 1. vsftpd简介 1.1 vsftpd是什么? ftp(File Transfer Protocol)文件传输协议.(实现不同操作系统之间文件的传输 ...

  3. Shell脚本调用ftp上传文件

    Shell脚本调用ftp上传文件 1.脚本如下 ftp -n<<! open x.x.x.x ###x.x.x.x为ftp地址 user username password ###user ...

  4. Python脚本打包成exe执行文件

    需求 一个教辅目录结构检查工具,目录结构是[书籍]-[章节]-[题目|答案]-[*.jpg],后台有个异步处理的服务,需要强依赖这个目录结构. 书籍解析是单独的pipeline,日志对用户不可见,这里 ...

  5. 开发错误日志之FTP协议传输文件问题

    从开发端用FTP协议向服务器(Linux系统)传输文件时,cat -A查询文件内容中行尾会有^M出现. 解决方案:改用SFTP协议上传文件.

  6. linux脚本:ftp自动传输文件

    使用Shell脚本实现ftp的自动上传下载 http://liwenge.iteye.com/blog/566515 open 192.168.1.171 user guest 123456cd /h ...

  7. ubuntu下把python脚本转为二进制字节码文件

    ubuntu下把python脚本转为二进制字节码文件 听语音 原创 | 浏览:354 | 更新:2017-12-22 14:48 1 2 3 4 5 6 7 分步阅读 自己拥有个几个python脚本文 ...

  8. python网络编程--FTP上传文件示例

    1.基础版(供学习了解原理使用,low) server服务端 import socket import struct import json server = socket.socket() ip_p ...

  9. python脚本-excel批量转换为csv文件

    pandas和SQL数据分析实战视频教程 https://study.163.com/course/courseMain.htm?courseId=1006383008&share=2& ...

随机推荐

  1. linux 如何查找命令的路径(which搜索系统命令,whichis搜索文件)

    http://hi.baidu.com/longredhao/item/911356ea2d8bed3687d9deed linux 下,我们常使用 cd ,grep,vi 等命令,有时候我们要查到这 ...

  2. cglib的动态代理

    前言 jdk中的动态代理通过反射类Proxy和InvocationHandler回调接口实现,要求委托类必须实现一个接口,只能对该类接口中定义的方法实现代理,这在实际编程中有一定的局限性. cglib ...

  3. 007.MFC_ComboBox_ListBox

    组合框.列表框 组合框的封装类:CComboBox 列表框的封装类:CListBox 一.创建名为ComboAndList的MFC工程,按照下图添加组件 修改static text Caption属性 ...

  4. 第二阶段:2.商业需求文档MRD:2.MRD-目标市场分析

    版本管理的变更人,属性,时间以及审核人都要严格的写清楚. MRD主要面向的是参与这个需求同级别的同时或主管,让大家更好的了解这个产品的各个方面,达成共识. 现在互联网的发展周期很短,不需要看4.5年, ...

  5. VC windows 多网卡情况下 获取当前网卡ip地址

    参考 代码如下 记录下以后用得到或者能帮到有需要的朋友 #include <iostream> #include <WinSock2.h> #include <Iphlp ...

  6. $Noip2014/Luogu2312$ 解方程

    $Luogu$ $Sol$ 枚举解+秦九韶公式计算+取模. $Code$ #include<iostream> #include<cstdio> #include<cst ...

  7. asp.net core 3.x 通用主机原理及使用

    一.前言 只是讲asp.net core 3.x通用主机的大致原理,这些东西是通过查看源码以及自己根据经验总结得来的,在文章中不会深入源码,因为个人觉得懂原理就晓得扩展点,后期碰到有需求的时候再仔细去 ...

  8. 使用百度NLP接口对搜狐新闻做分类

    一.简介 本文主要是要利用百度提供的NLP接口对搜狐的新闻做分类,百度对NLP接口有提供免费的额度可以拿来练习,主要是利用了NLP里面有个文章分类的功能,可以顺便测试看看百度NLP分类做的准不准.详细 ...

  9. 入门Grunt前端构建工具

    1. 全局安装 grunt:(倘若之前电脑安装过,则跳过此步骤) $ cnpm install -g grunt-cli 2. 作为项目的开发依赖(devDependencies)安装: (此步骤会自 ...

  10. 【转】15个超炫的HTML5效果

    英文原文:http://www.hongkiat.com/blog/15-html5-experiments/     翻译:iteye 乔布斯没有给Flash任何机会,微软新推出的Windows 8 ...