最近在做一个大数据风控的项目,需要从ftp服务器上下载文件到本地服务器,于是写了一个通用脚本与大家分享一下。
具体的需求是这样的:
一、服务器信息:
ftp服务器IP:192.168.216.121
登陆用户 :ftp_test
登陆密码 :ftp_test
数据路径 :/home/ftp_test/数据日期
二、实现要求:
1、shell实现
2、文件获取后对文件的大小和数据条数进行核对,
如果和.ok文件中一致则通过,将文件转移到目标目录;
如果不一致,删除,隔5分钟重新获取
3、日志文件要写全
具体的实现思路:先去判断ftp服务器上是否有当前数据日期的文件,然后在本地服务器上创建要接受数据的文件夹,再连接ftp服务器下载对应文件,下载到本地做数据校验,因为是有校验文件的所以只需要把数据文件和校验文件做个比较就可以了,如果没有校验文件就要用到md5校验,最后做了一个死循环,如果传输成功就跳出,如果失败就休眠5min后再获取,直到获取到为止。
这里我将脚本改成的动态传参的形式,需要传入两个参数:日期、表名,调用更加灵活。
#! /bin/bash
host_ip=192.168.216.121 #ftp服务器ip
user_id=ftp_test #ftp服务器用户名
pass_word=ftp_test #ftp服务器密码
remote_dir=/home/ftp_test #远程主机路径
local_dir=/home/ftp_test #本机路径
log_dir=/export/log/result.txt #ftp服务器显示日志路径
data_time=$1 #数据文件日期
final_local=${data_time}"_SU" #本地最终地址
file_name="CHAMC-EDW-RPW_"$2"-"$1"-ALL" #文件名称
data_file=${file_name}".dat" #数据文件名称
check_file=${file_name}".ok" #检验文件名称
while :
do
exec 1>>${local_dir}/${data_time}"getDataFromFtp.log"
exec 2>>${local_dir}/${data_time}"getDataFromFtp.log"
echo "***************`date +%Y%m%d` `date +%H`:`date +%M`:`date +%S` 开始执行脚本:***************"
exec 6>&1 1>${log_dir}
ftp -n ${host_ip} <<EOF
user ${user_id} ${pass_word}
cd ${remote_dir}/${data_time}
ls *
close
bye
EOF
exec 1>&6
exec 6>&-
#判断ftp服务器上文件是否存在
if `grep -q ${data_file} ${log_dir}` ;then
echo ${data_file}"文件已经存在于FTP服务器!"
else
echo ${data_file}"文件在FTP服务器上不存在!"
fi
#在本地服务器上创建当前跑批日期的文件夹
if [ ! -d ${local_dir}/${data_time} ];then
mkdir ${local_dir}/${data_time}
mkdir ${local_dir}/${final_local}
echo "***************文件夹创建完成!***************"
else
echo "***************文件夹已经存在!***************"
fi
#连接远程ftp服务器,并作数据校验,获取文件到本地
ftp -n ${host_ip} <<EOF
user ${user_id} ${pass_word}
ascii
cd ${remote_dir}/${data_time}
lcd ${local_dir}/${data_time}
prompt
mget ${file_name}.*
bye
EOF
cd ${local_dir}/${data_time}
file_num=$(cat "${data_file}" |wc -l)
echo "数据文件行数是:"${file_num}
check_num=$(awk -F"," '{print $3}' "${check_file}")
echo "校验文件中行数是:"${check_num}
file_fact_size=$(du -h "${data_file}" | awk '{print $1}')
echo "数据文件实际的大小是:"${file_fact_size}
file_check_size=$(awk -F"," '{print $1}' "${check_file}")
echo "校验文件中大小是:"${file_check_size}
if [ ${file_num} -eq ${check_num} ] && [ ${file_fact_size} == ${file_check_size} ];then
echo "***************`date +%Y%m%d` `date +%H`:`date +%M`:`date +%S` FTP数据传输完成!***************"
cp ${local_dir}/${data_time}/${data_file} ${local_dir}/${final_local}
break
else
echo "***************`date +%Y%m%d` `date +%H`:`date +%M`:`date +%S` FTP数据传输错误!***************"
rm -rf ${local_dir}/${data_time}/${file_name}".*"
sleep 300
fi
done