最近有两个需求,一个是每天定时从各个服务器下拷贝文件到一台挂有大磁盘的服务器,把每台服务器的文件区分拷贝过去并删除本服务器的文件。
第二个需求是把挂有大磁盘的服务器上备份的文件通过ftp传送出去。(不要问我为啥不直接从各个服务器通过ftp传出去而要绕一层挂有大磁盘的服务器,因为ftp提供的太晚了。做第一个需求的时候还没有第二个需求)
本来是做java开发的,但是公司没有服务器运维人员,所以自己什么都要解决。研究了下shell脚本的scp命令,最初的方案是把shell脚本和scp交互分开,然后在主脚本里边调用scp的交互脚本,最后无意间发现shell竟然有EOF这个功能(别笑,本人linux除了正常的操作和查询基本上没研究)废话不说,直接上脚本,做个记录。
expect交互需要安装对应的软件。tcl8.4.11-src expect5.45
参考链接 http://blog.csdn.net/jdbc/article/details/42001695
脚本一:
定时从指定目录拷贝到另一台服务器的指定目录,拷贝成功删除本地的文件。
#!/bin/bash
#owner huiyunfei
NOW_TIME=`date '+%Y-%m-%d %H:%M:%S'`
echo "$NOW_TIME begin start backup.sh"
FROM_DIR=/data/image
TAR_DIR=/data/temp
LAST_DATE=$(date -d last-day +%Y%m%d)
cd $FROM_DIR
if [ ! -d "$FROM_DIR/$LAST_DATE" ]; then
echo "$NOW_TIME $LAST_DATE dir is not exist,begin exit"
exit
fi
if [ ! -f "$TAR_DIR/$LAST_DATE.tar.gz" ]; then
tar -zcf $TAR_DIR/$LAST_DATE.tar.gz $LAST_DATE/
echo "tar $LAST_DATE.tar.gz success"
else
echo "tar $LAST_DATE.tar.gz is exist"
fi
TO_HOST="xx.xx.xx.xx"
USER="xx"
PASSWD="xx"
TO_DIR="/date/188/"
/usr/expect/bin/expect <<-EOF
set timeout -1
spawn scp -o "StrictHostKeyChecking no" $TAR_DIR/$LAST_DATE.tar.gz $USER@$TO_HOST:$TO_DIR
expect "assword:"
send "$PASSWD\n"
expect "100%"
expect eof
EOF
echo "scp $TO_HOST success"
rm -rf $FROM_DIR/$LAST_DATE
rm -rf $TAR_DIR/$LAST_DATE.tar.gz
echo "rm dir,dir.tar.gz success"
echo "$NOW_TIME stop backup.sh"
第二个脚本描述的比较详细。
#!/bin/bash
#owner huiyunfei
#2018-01-24
#
#目标:
#本地文件夹/test1 /test2 /test3 都会有昨天的tar.gz
#例:/test1/20180123.tar.gz /test2/20180123.tar.gz /test3/20180123.tar.gz
#上传到ftp data/test1 data/test2 data/test3
#并生成对应的总上传日志记录 ftp_run_log,上传的同时如果出错要生成对应文件的error.log并退出脚本
#上传出错会sleep3分钟并循环三次,如果三次内成功则删除对应的error.log,本地的tar.gz并继续上传下一个
#总任务完成后删除本地文件夹下对应的文件,退出脚本
#脚本放环境需要修改以下地方:
#ftp_run_log 总任务日志记录
#ftp_err_dir 单个文件夹错误日志记录(循环三次成功则会被删除)
#local_file_dir 本地待上传文件所在子文件夹
#ftp_file_dir ftp待保存子文件夹
#server_arr 待上传文件夹列表
#ftp_ip
#ftp_user ftp_passwd
#
ftp_run_log='/home/yunfei/logs/ftprunlogs/cron_ftp_run.log'
ftp_err_dir="/home/yunfei/logs/temperrorlogs/"
echo "`date +%F" "%T":"%N` Script : $0 start runing..." >> ${ftp_run_log}
t_last_day=`date -d last-day +%Y%m%d`
put_file_name="${t_last_day}.tar.gz" #昨天的文件 20180123
ftp_ip=116.62.175.185
ftp_user=xx
ftp_passwd=xx
##########################
#FTP自动化上传函数 有错误就return1
send_file(){
ftp -i -n ${ftp_ip} 21 2>$3 << _EOF_
user ${ftp_user} ${ftp_passwd}
passive
bin
lcd $1
cd $2
put ${put_file_name}
bye
_EOF_
#统计前面FTP运行输出的错误日志记录行数
log_count=`cat $3|wc -l`
[ ${log_count} -eq 0 ] && return 0 || return 1
}
##########################
#调用FTP上传函数,返回until需要的状态值
#每次错误睡眠120秒,总循环三次
function run_send_file(){
send_file $1 $2 $3
if [ $? -eq 0 ];then
echo "`date +%F" "%T":"%N` Send : $5_${put_file_name} to ftp_server was successfully." >> ${ftp_run_log}
return 0
else
echo "`date +%F" "%T":"%N` Send : $5_${put_file_name} more than $4 time." >> ${ftp_run_log}
sleep 120
return 1
fi
}
##########################
#循环操作每个文件夹的文件
handle(){
local_file_dir="/home/yunfei/data/$1/"
ftp_file_dir="/test/$1"
ftp_err_log="${ftp_err_dir}$1_${put_file_name}_error.log"
#如果某个文件夹或者文件夹内不存在对应的tar.gz直接进行下一个文件夹
if [ ! -d ${local_file_dir} ]; then
echo "${local_file_dir} dir is not exist,begin next..." >> ${ftp_run_log}
return
fi
if [ ! -f ${local_file_dir}${put_file_name} ]; then
echo "${put_file_name} file is not exist,begin next..." >> ${ftp_run_log}
return
fi
#出错则循环3次,总共6分钟
x=1
i=1
until [ "$i" -eq 0 ];do
[ $x -gt 3 ] && {
echo "`date +%F" "%T":"%N` Send : $1_${put_file_name} to ftp_server was failed, Please check..." >> ${ftp_run_log}
exit
}
run_send_file ${local_file_dir} ${ftp_file_dir} ${ftp_err_log} $x $1
i=`echo $?`
x=`expr $x + 1`
done
#删除FTP产生的临时错误日志文件
[ -f ${ftp_err_log} ] && rm ${ftp_err_log}
#删除本地数据
#rm -rf ${local_file_dir}${put_file_name}
}
server_arr=("187" "188" "189" )
for server in ${server_arr[@]}; do
handle $server;
done
echo "`date +%F" "%T":"%N` Script : $0 done." >> ${ftp_run_log}