一直以来项目的文件没有备份,最近需要增加备份,本来以为备份是IT的工作,结果IT说工作忙,拖了半个月给分配完ftp服务器后说不给备份,需要我们开发自己备份。。。我特么***
对于ftp备份,咱是没有经验的,IT给提示了一个工具:lftp。
关于lftp的介绍可以看这篇文章:https://blog.csdn.net/weixin_43135696/article/details/121541807,其中lftp -c命令我没搞懂到底要怎么执行,-c后面的cmd命令总提示不存在。
而备份文件主要用的是lftp mirror命令,参考:https://blog.51cto.com/riverxyz/1869476,总结如下:
mirror [OPTS] [source [target]]
[opts]参数如下:
-c, --continue 续传上次的任务 -e, --delete 删除远程目录上不存在的文件(删的是本地啊注意) --delete-first 在传输新文件之前删除旧的文件 --depth-first 进入下一层目录优先于文件传输 -s, --allow-suid 根据远程站点设置suid/sgid比特位 --allow-chown 尝试将自己设置为文件所有者和所有组 --ascii 使用ascii方式传输(隐含了--ignore-size) --ignore-time 决定是否下载时忽略时间因素 --ignore-size 决定是否下载时忽略文件大小因素 --only-missing 只下载缺少的文件 --only-existing 只下载已经存在于目标文件夹中的文件 -n, --only-newer 只下载新文件(-c参数无法工作) --no-empty-dirs 不创建空文件夹(隐含了--depth-first) -r, --no-recursion 不进入子文件夹 --no-symlinks 不创建符号链接 -p, --no-perms 不设置文件权限 --no-umask 不使用文件预设权限 -R, --reverse 反向镜像(上传文件,注意大写) -L, --dereference 将符号链接作为 文件下载 -N, --newer-than=SPEC 只下载比指定时间晚的文件 --on-change=CMD 只要有文件或文件夹存在差异就执行命令CMD --older-than=SPEC 只下载比指定时间早的文件 --size-range=RANGE 只下载大小在指定区间上的文件 -P, --parallel[=N] 并行下载N个文件 --use-pget[-n=N] 使用pget传输每个文件 --loop 循环直到找不到差异 -i RX, --include RX 包括相匹配的文件 -x RX, --exclude RX 不包括相匹配的文件 -I GP, --include-glob GP 包括相匹配的文件 -X GP, --exclude-glob GP 不包括相匹配的文件 -v, --verbose[=level] 输出等级,加该参数输出执行详情,不加则在底部变动显示。 --log=FILE 将执行的lftp命令写入文件FILE --script=FILE 将lftp命令写入文件FILE,但不执行 --just-print, --dry-run 与--script=-相同 --use-cache 使用缓存目录列表
我的想法是每天定时将本地文件夹备份到远程ftp服务器上,所以执行
lftp -e "mirror --reverse --only-missing --only-newer 本地文件夹 ftp文件夹 --parallel=5 --log=日志.log" 账号:密码@ftp服务器ip 或 lftp -u 账号,密码 -e "mirror --reverse --only-missing --only-newer --verbose 本地文件夹 ftp文件夹 --parallel=3 --log=日志.log" ftp服务器ip
以上两个方式效果是一样的。其中参数 --verbose可以在控制台输出执行详情,不想输出的可以不加,执行完成最终会显示本次执行上传了多少文件和创建了多少文件夹。
现实远非单个文件夹,由于早期设计原因,各个模块的文件夹是存在不同的目录下的,而且命名方式“各显神通”,有的以模块为根目录,有的以年月为根目录,有的模块只有根目录一级目录(所有的文件都在一级目录下),有的模块次级目录是年月而有的次级目录是年月日...
针对已经存在的目录尽量不进行大的变动了,但对于文件量大的模块还是不得不进行改造,比如上面说的只有模块一级目录的文件夹如果每日增量文件不小则需要添加年月(甚至年月日)次级目录。历史的目录只需按上面的命令执行全量备份即可,对于每日的增量文件进行定时任务的增量备份。
按以上几种情况整合bat脚本如下:
#!/bin/bash # 每小时执行一次同步文件到ftp服务器,要考虑跨天情况 # 设置今天对应的年月(yyyy-mm)、日期(dd)、时间(yyyy-mm-dd HH:MM:SS,注意中间空格的方式) date_ym=`date +%Y-%m` date_d=`date +%d` date_ymd=`date +%Y-%m-%d" "%H:%M:%S` # 半年前日期 halfyear_ymd=`date -d "-179 day" +%Y-%m-%d` # 半年前对应日期再往前一小时所属日期,只能按小时数(24*179+1) halfyear_last_hour_ymd=`date -d "-4297 hour" +%Y-%m-%d` # 当前时间往前一小时所属年月日 last_hour_ymd=`date -d "-1 hour" +%Y-%m-%d` last_hour_ym=`date -d "-1 hour" +%Y-%m` last_hour_d=`date -d "-1 hour" +%d` last_hour_h=`date -d "-1 hour" +%H` echo $date_ymd"开始同步------------------" echo $last_hour_d echo $last_hour_ym echo $last_hour_ymd echo $last_hour_h echo $halfyear_ymd echo $halfyear_last_hour_ymd # 将执行日志保存进脚本目录下属日志文件夹/年月日文件夹,先创建文件夹,否则报错不存在目录 mkdir -p /本地脚本目录/logs/$last_hour_ym/$last_hour_d/ # 同步一小时前所在月份文件夹,比如文件夹2022-10 if [ -d "/本地目录/"$last_hour_ym ]; then echo $last_hour_ym lftp -u 账号,密码 ftp服务器ip << EOF mirror --reverse --only-missing --only-newer /本地目录/$last_hour_ym ftp服务器目录/$last_hour_ym --parallel=3 --log=/本地脚本目录/logs/$last_hour_ym/$last_hour_d/$last_hour_d-$last_hour_h.log bye EOF else echo $last_hour_ym"不存在" fi # 同步具体分类文件夹,不带年月子文件夹 for item in 模块1目录 模块2目录 模块N目录 do echo $item; lftp -u 账号,密码 ftp服务器ip << EOF mirror --reverse --only-missing --only-newer /本地目录/$item ftp服务器目录/$item --parallel=3 --log=/本地脚本目录/logs/$last_hour_ym/$last_hour_d/$item-$last_hour_h.log bye EOF done # 同步具体分类文件夹,带年月(模块名/2022-10)子文件夹 for item in 模块11目录 模块22目录 模块NN目录 do if [ -d "/本地目录/"$item"/"$last_hour_ym ]; then echo $item; lftp -u 账号,密码 ftp服务器ip << EOF mirror --reverse --only-missing --only-newer /本地目录/$item/$last_hour_ym ftp服务器目录/$item/$last_hour_ym --parallel=3 --log=/本地脚本目录/logs/$last_hour_ym/$last_hour_d/$item-$last_hour_h.log bye EOF else echo $item"/"$last_hour_ym"不存在" fi done # 同步具体分类文件夹,带年月日(模块名/2022-10-29)子文件夹的 for item in 模块111目录 模块222目录 模块NNN目录 do if [ -d "/本地目录/"$item"/"$last_hour_ymd ]; then echo $item; lftp -u 账号,密码 ftp服务器ip << EOF mirror --reverse --only-missing --only-newer /本地目录/$item/$last_hour_ymd ftp服务器目录/$item/$last_hour_ymd --parallel=3 --log=/本地脚本目录/logs/$last_hour_ym/$last_hour_d/$item-$last_hour_h.log bye EOF else echo $item"/"$last_hour_ymd"不存在" fi done echo '同步结束----------------------'