zoukankan      html  css  js  c++  java
  • 【原创】一个shell脚本记录(实现rsync生产文件批量迁移功能)

    #!/bin/bash
    #Date:2018-01-08
    #Author:xxxxxx
    #Function:xxxxxx
    #Change:2018-01-17
    #
    
    #设置忽略CTRL+C信号
    trap 'my_exit;exit' SIGINT SIGTERM SIGQUIT
    
    #开启DEBUG模式
    #set -x
    
    #如果有命令执行返回值为非0,那么脚本将结束,不再继续执行
    # set -e
    
    #导入rsync使用的密码
    export RSYNC_PASSWORD='xxxxxx'
    
    #设置脚本涉及的目录变量
    pathdir=$(cd $(dirname $0);pwd)
    #源主机同步到本机的临时目录
    tmpdir='/data/migrate_tmp'
    # tmpdir='/data/migrate_tmp/tmp'		#测试用
    #管理机
    domain_m=("cms.domain.com" "pic.domain.com")
    youxi_m=("/data1/www/abc.test.com" "/data1/www/pic.domain.com")
    # youxi_m=("/data/migrate_tmp/abc.test.com" "/data/migrate_tmp/pic.domain.com")	#测试用
    #模板机
    domain_t='cms.domain.com'
    youxi_t='/data2/www/abc.test.com'
    #web机
    domain_web=''
    youxi_web='/data/webapps'
    #youxi_web='/data/migrate_tmp/webapps'	#测试用
    #图片机
    domain_pic='pic.domain.com'
    youxi_pic='/data/webapps/pic.domain.com'
    
    #判断临时目录是否存在,若不存在则创建
    [ -d ${tmpdir} ] && rm -rf ${tmpdir}/* || mkdir -p ${tmpdir}
    
    #备份目录
    # [ -d /data/fabuqi_bak ] && mkdir /data/fabuqi_bak
    
    #进入到脚本所在的目录
    cd ${pathdir}
    
    #定义grep查找需要替换的文件列表正则
    grep_re="img.dwstatic.com|img[1-5].dwstatic.com|pic[1-5].domain.com|pic[0-5]1.domain.com|public.domain.com|pic.domain.(com|cn)"
    
    #trap的执行函数
    function my_exit(){
    	echo trap_handle_time: $(date "+%Y-%m-%d %H:%M:%S")
    	echo "exit"
    }
    
    #脚本使用说明函数
    function usage(){
    	echo "Usage: $0 [OPTIONS]"
    	echo "   - Here to display help info ."
    	echo "   - The args is only two ."
    	echo "   - OPTIONS: [ all | zhuanqu_ID | 专区ID ] ."
    	echo "   example: /bin/bash migrate.sh zxyzxy "
    	exit 1
    }
    
    #logger function
    function log_info(){
    	DATA_N=$(date "+%Y-%m-%d %H:%M:%S")
    	USER_N=$(whoami)
    	echo "${DATA_N} ${USER_N} execute $0 [INFO] $@" | tee -a ${pathdir}/migrate.log
    }
    
    #配置变量函数,sync_dir是同步的源主机子目录,destdir是新发布器目标目录。
    function config_and_rsync_single(){
    	#从源主机的哪个机器同步数据
    	rsync_from=${2}
    	#目标同步的目录
    	if [[ "${rsync_from}" == "xxx.xxx.xxx.xxx" ]]; then
    		#拉取单个专区文件资源,保留文件时间属性
    		for i in `seq 0 $(expr ${#domain_m[*]} - 1)`
    		do
    			log_info "set the sync_dir and destdir value ..."
    			sync_dir=${domain_m[$i]}
    			destdir=${youxi_m[$i]}
    			#备份目录
    			log_info "backup the destdir ..."
    			cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"`
    
    			#将目标目录拷贝到临时目录,如果临时目录已经存在,就直接拷贝文件,如果不存在就创建临时目录在拷贝目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。
    			log_info "create tmpdir ..."
    			[ -d ${tmpdir}/${sync_dir} ] && cp -rpvu ${destdir}/* ${tmpdir}/${sync_dir} 2>>${pathdir}/migrate.log || mkdir -p ${tmpdir}/${sync_dir} && cp -rpvu ${destdir}/* ${tmpdir}/${sync_dir} 2>>${pathdir}/migrate.log
    
    			log_info "Start to get ${1} files ......"
    			rsync -avuzt game_test@${rsync_from}::game_test/${sync_dir}/${1} ${tmpdir}/${sync_dir} | tee -a ${pathdir}/migrate.log
    			log_info "Start to execute update_single_id function ......"
    			update_single_id ${tmpdir}/${sync_dir} ${1} ${destdir}
    		done
    		log_info "建立专区对应的软连接 ..."
    		ln -nfs /data1/www/abc.test.com/${id} /data1/webapps/${id}.domain.com 2>>${pathdir}/migrate.log
    		chown -R www-data:www-data /data1/webapps/${id}.domain.com
    	elif [[ "${rsync_from}" == "xxx.xxx.xxx.xxx" ]]; then
    		log_info "set the sync_dir and destdir value ..."
    		sync_dir=${domain_t}
    		destdir=${youxi_t}
    		#备份目录
    		log_info "backup the destdir ..."
    		cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"`
    
    		#将目标目录拷贝到临时目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。
    		log_info "create tmpdir ..."
    		cp -rpvu ${destdir}/* ${tmpdir} 2>>${pathdir}/migrate.log
    
    		log_info "Start to get ${1} files ......"
    		rsync -avuzt game_test@${rsync_from}::game_test/${sync_dir}/${1} ${tmpdir}/ | tee -a ${pathdir}/migrate.log
    		log_info "Start to execute update_single_id function ......"
    		update_single_id ${tmpdir} ${1} ${destdir}
    		log_info "建立专区对应的软连接 ..."
    		ln -snf ${destdir}/${id} /data/data1/www/abc.test.com/${id}.domain.com 2>>${pathdir}/migrate.log
    		chown -R www-data:www-data /data/data1/www/abc.test.com/${id}.domain.com
    	elif [[ "${rsync_from}" == "xxx.xxx.xxx.xxx" ]]; then
    		log_info "set the sync_dir and destdir value ..."
    		sync_dir=${domain_web}
    		destdir=${youxi_web}
    		#备份目录
    		log_info "backup the destdir ..."
    		cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"`
    
    		#将目标目录拷贝到临时目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。
    		log_info "create tmpdir ..."
    		cp -rpvu ${destdir}/* ${tmpdir} 2>>${pathdir}/migrate.log
    
    		log_info "Start to get ${1} files ......"
    		rsync -avuzt game_test@${rsync_from}::game_test/${1}.domain.com ${tmpdir}/ | tee -a ${pathdir}/migrate.log
    		log_info "Start to execute update_single_id function ......"
    		update_single_id ${tmpdir} ${1}.domain.com ${destdir}
    
    		log_info "Start to backup ${1} nginx configure file......"
    		[ -d /data/services/nginx_vhost_bak ] || mkdir -p /data/services/nginx_vhost_bak
    		cp -pvu /data/services/nginx_vhost/${1}.*.conf /data/services/nginx_vhost_bak/ 2>>${pathdir}/migrate.log
    		log_info "Start to rsync ${1} nginx configure file ......"
    		rsync -avuzt game_test@${rsync_from}::nginx_test/${1}.*.conf /data/services/nginx_vhost/
    		log_info "update the ${1} nginx conf,please to reload nginx service by manual ..."
    		# service nginx reload
    	else
    		log_info "set the sync_dir and destdir value ..."
    		sync_dir=${domain_pic}
    		destdir=${youxi_pic}
    		#备份目录
    		log_info "backup the destdir ..."
    		cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"`
    
    		#将目标目录拷贝到临时目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。
    		log_info "create tmpdir ..."
    		cp -rpvu ${destdir}/* ${tmpdir} 2>>${pathdir}/migrate.log
    
    		log_info "Start to get ${1} files ......"
    		rsync -avuzt game_test@${rsync_from}::game_test/${sync_dir}/${1} ${tmpdir}/ | tee -a ${pathdir}/migrate.log
    		log_info "Start to execute update_single_id function ......"
    		update_single_id ${tmpdir} ${1} ${destdir}
    	fi
    }
    
    #迁移单个专区函数
    function update_single_id(){
    	_tmpdir=${1}
    	id=${2}
    	_destdir=${3}
    	cd ${_tmpdir}
    	log_info "replace contexts in the files that in the ${id} directory ..."
    	#判断目录是否为空
    	if [ "`ls -A ${_tmpdir}/${id}`" = "" ]; then
    		log_info "the ${id} is indeed empty."
    	#判断目录及其子目录是否为空
    	elif [ "`find ${_tmpdir}/${id}/* -type f`" = "" ]; then
    		log_info "the ${id} and subdir are empty."
    	#判断是否有文件需要做内容替换
    	elif [ "`grep -rEl ${grep_re} ${_tmpdir}/${id}/*`" = "" ]; then
    		log_info "the ${id} not files need to replace."
    	#不为空时执行修改文件内容操作
    	else
    		log_info "Start to sed ......"
    		sed -i -e 's/img.dwstatic.com/img.game.dwstatic.com/g' 
    		-e 's/img(.).dwstatic.com/img1.game.dwstatic.com/g' 
    		-e 's/pic(.).domain.com/img1.game.dwstatic.com/g' 
    		-e 's/pic01.domain.com/img.game.dwstatic.com/g' 
    		-e 's/pic(.)(.).domain.com/img1.game.dwstatic.com/g' 
    		-e 's/public.domain.com/publicgame.domain.com/g' 
    		-e 's/pic.domain.(com|cn)/img.game.dwstatic.com/g' $(grep -rEl ${grep_re} ${_tmpdir}/${id}/*)
    	fi
    
    	if [ -d ${_destdir}/${id} ];then
    		log_info "the ${id} is a exist id,backup old ${id} dirs ..."
    		[ -d /data/fabuqi_bak/${id}_bak ] && log_info "the ${id}_bak is exist,not need to backup ..." || cp -rfp ${_destdir}/${id} /data/fabuqi_bak/${id}_bak
    		log_info "replace old ${id} dirs by new ${id} dirs ..."
    		#同步专区目录到新发布器目标目录中,只会在源文件的更改时间较目标文件更新时或是目标文件并不存在时,才复制文件,保留文件时间属性
    		cp -rpvu ${_tmpdir}/${id}/* ${_destdir}/${id}/ | tee -a ${pathdir}/migrate.log
    		chown -R www-data:www-data ${_destdir}/${id}
    	else
    		log_info "the ${id} is a new id,not to backup."
    		#同步专区目录到新发布器目标目录中
    		cp -rpvu ${_tmpdir}/${id} ${_destdir}/${id} | tee -a ${pathdir}/migrate.log
    		chown -R www-data:www-data ${_destdir}/${id}
    	fi
    
    	log_info "update_single_id task done."
    }
    
    #配置变量函数,sync_dir是同步的源主机子目录,destdir是新发布器目标目录。
    function config_and_rsync_all(){
    	#从源主机的哪个机器同步数据
    	rsync_from=${1}
    	#目标同步的目录
    	if [[ "${rsync_from}" == "xxx.xxx.xxx.xxx" ]]; then
    		#拉取所有专区文件资源,保留文件时间属性
    		for i in `seq 0 $(expr ${#domain_m[*]} - 1)`
    		do
    			log_info "set the sync_dir and destdir value ..."
    			sync_dir=${domain_m[$i]}
    			destdir=${youxi_m[$i]}
    			#备份目录
    			log_info "backup the destdir ..."
    			cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"`
    
    			#将目标目录拷贝到临时目录,如果临时目录已经存在,就直接拷贝文件,如果不存在就创建临时目录在拷贝目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。
    			log_info "create tmpdir ..."
    			[ -d ${tmpdir}/${sync_dir} ] && cp -rpvu ${destdir}/* ${tmpdir}/${sync_dir} || mkdir -p ${tmpdir}/${sync_dir} && cp -rpvu ${destdir}/* ${tmpdir}/${sync_dir}
    
    			log_info "Start to get ${sync_dir} all files ......"
    			rsync -avuzt game_test@${rsync_from}::game_test/${sync_dir}/* ${tmpdir}/${sync_dir} | tee -a ${pathdir}/migrate.log
    			log_info "Start to execute update_all_id ${sync_dir} function ......"
    			update_all_id ${tmpdir}/${sync_dir} ${destdir}
    		done
    		for id in $(ls ${tmpdir}/${domain_m[0]})
    		do
    			log_info "建立专区对应的软连接 ..."
    			ln -nfs /data1/www/abc.test.com/${id} /data1/webapps/${id}.domain.com
    			chown -R www-data:www-data /data1/webapps/${id}.domain.com
    		done
    	elif [[ "${rsync_from}" == "xxx.xxx.xxx.xxx" ]]; then
    		log_info "set the sync_dir and destdir value ..."
    		sync_dir=${domain_t}
    		destdir=${youxi_t}
    		#备份目录
    		log_info "backup the destdir ..."
    		cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"`
    
    		#将目标目录拷贝到临时目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。
    		log_info "create tmpdir ..."
    		cp -rpvu ${destdir}/* ${tmpdir}/
    
    		log_info "Start to get all files ......"
    		rsync -avuzt game_test@${rsync_from}::game_test/${sync_dir}/* ${tmpdir}/ | tee -a ${pathdir}/migrate.log
    		log_info "Start to execute update_all_id function ......"
    		update_all_id ${sync_dir} ${destdir}
    		for id in $(ls ${tmpdir}/${sync_dir})
    		do
    			log_info "建立专区对应的软连接 ..."
    			ln -snf ${destdir}/${id} /data/data1/www/abc.test.com/${id}.domain.com
    			chown -R www-data:www-data /data/data1/www/abc.test.com/${id}.domain.com
    		done
    	elif [[ "${rsync_from}" == "xxx.xxx.xxx.xxx" ]]; then
    		log_info "set the sync_dir and destdir value ..."
    		sync_dir=${domain_web}
    		destdir=${youxi_web}
    		#备份目录
    		log_info "backup the destdir ..."
    		cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"`
    
    		#将目标目录拷贝到临时目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。
    		log_info "create tmpdir ..."
    		cp -rpvu ${destdir}/* ${tmpdir}/
    
    		log_info "Start to get all files ......"
    		rsync -avuzt game_test@${rsync_from}::game_test/* ${tmpdir}/ | tee -a ${pathdir}/migrate.log
    		log_info "Start to execute update_all_id function ......"
    		update_all_id ${sync_dir} ${destdir}
    
    		log_info "Start to backup all nginx configure file......"
    		cp -r /data/services/nginx_vhost /data/services/nginx_vhost_bak
    		log_info "Start to rsync all nginx configure file ......"
    		rsync -avuzt game_test@${rsync_from}::nginx_test/* /data/services/nginx_vhost/
    		log_info "update the nginx conf,please to reload nginx service by manual ..."
    		# service nginx reload
    	else
    		log_info "set the sync_dir and destdir value ..."
    		sync_dir=${domain_pic}
    		destdir=${youxi_pic}
    		#备份目录
    		log_info "backup the destdir ..."
    		cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"`
    
    		#将目标目录拷贝到临时目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。
    		log_info "create tmpdir ..."
    		cp -rpvu ${destdir}/* ${tmpdir}/
    
    		log_info "Start to get all files ......"
    		rsync -avuzt game_test@${rsync_from}::game_test/${sync_dir}/* ${tmpdir}/ | tee -a ${pathdir}/migrate.log
    		log_info "Start to execute update_all_id function ......"
    		update_all_id ${sync_dir} ${destdir}
    	fi
    }
    
    #批量迁移所有专区的函数
    function update_all_id(){
    	_tmpdir=${1}
    	_destdir=${2}
    	cd ${_tmpdir}
    	for id in $(ls ${_tmpdir}/)
    	do
    		if [[ ${id} == "ssss" || ${id} == "testsslj" ]]; then
    			log_info "skip the ${id}."
    		elif [[ -f ${_tmpdir}/${id} ]]; then
    			log_info "the ${_tmpdir}/${id} is a file,not dir,please check it and sync by manual."
    		else
    			log_info "migrate ${id} start..."
    			cd ${_tmpdir}/${id}
    			log_info "replace contexts in the files that in the ${id} directory ..."
    			#判断目录是否为空
    			if [ "`ls -A ${_tmpdir}/${id}`" = "" ]; then
    				log_info "the ${id} is indeed empty."
    			#判断目录及其子目录是否为空
    			elif [ "`find ${_tmpdir}/${id}/* -type f`" = "" ]; then
    				log_info "the ${id} and subdir are empty."
    			#判断是否有文件需要做内容替换
    			elif [ "`grep -rEl ${grep_re} ${_tmpdir}/${id}/*`" = "" ]; then
    				log_info "the ${id} not files need to replace."
    			#不为空时执行修改文件内容操作
    			else
    				log_info "Start to sed ......"
    				sed -i -e 's/img.dwstatic.com/img.game.dwstatic.com/g' 
    				-e 's/img(.).dwstatic.com/img1.game.dwstatic.com/g' 
    				-e 's/pic(.).domain.com/img1.game.dwstatic.com/g' 
    				-e 's/pic01.domain.com/img.game.dwstatic.com/g' 
    				-e 's/pic(.)(.).domain.com/img1.game.dwstatic.com/g' 
    				-e 's/public.domain.com/publicgame.domain.com/g' 
    				-e 's/pic.domain.(com|cn)/img.game.dwstatic.com/g' $(grep -rEl ${grep_re} ${_tmpdir}/${id}/*)
    			fi
    
    			if [ -d ${_destdir}/${id} ]; then
    				log_info "the ${id} is a exist id,backup old ${id} dirs ..."
    				[ -d /data/fabuqi_bak/${id}_bak ] && log_info "the ${id}_bak is exist,not need to backup ..." || cp -rfp ${_destdir}/${id} /data/fabuqi_bak/${id}_bak
    				log_info "replace old ${id} dirs by new ${id} dirs ..."
    				#同步专区目录到新发布器目标目录中,只会在源文件的更改时间较目标文件更新时或是目标文件并不存在时,才复制文件,保留文件时间属性
    				cp -rpvu ${tmpdir}/${1}/${id}/* ${_destdir}/${id}/ | tee -a ${pathdir}/migrate.log
    				chown -R www-data:www-data ${_destdir}/${id}
    			else
    				log_info "the ${id} is a new id,not to backup."
    				#同步专区目录到新发布器目标目录中
    				cp -rpvu ${tmpdir}/${1}/${id} ${_destdir}/${id} | tee -a ${pathdir}/migrate.log
    				chown -R www-data:www-data ${_destdir}/${id}
    			fi
    
    			log_info "migrate ${id} end..."
    		fi
    	done
    	log_info "update_all_id task done."
    }
    
    #主函数
    function main(){
    	domain_ip=("xxx.xxx.xxx.xxx" "xxx.xxx.xxx.xxx" "xxx.xxx.xxx.xxx" "xxx.xxx.xxx.xxx")
    	youxi_ip=("xxx.xxx.xxx.xxx" "xxx.xxx.xxx.xxx" "xxx.xxx.xxx.xxx" "xxx.xxx.xxx.xxx")
    	#限制执行脚本的ip,并且制定对应的新管理机从源主机管理机拉取文件,其他类型的机器一样,否则,不执行脚本。
    	for index in `seq 0 $(expr ${#domain_ip[*]} - 1)`
    	do
    		if [ $(ifconfig | grep ${youxi_ip[$index]} | wc -l) -eq 1 ]; then
    			ip=${domain_ip[$index]}
    			break
    		else
    			ip="error_x"
    			continue
    		fi
    	done
    
    	if [ $# -ne 1 ]; then
    		usage
    	# elif [[ ${1} == "all" ]]; then
    	# 	config_and_rsync_all ${2}
    	elif [[ ${1} == "ssss" || ${1} == "testsslj" ]]; then
    		log_info "skip the ${1}."
    	else
    		if [[ ${ip} == "error_x" ]]; then
    			log_info "this host $(ifconfig | grep 'inet addr'|awk '{print $2}'| awk -F: '{print $2}'| grep -vE '^$' | head -1) no exist youxi_ip list,please add this ip to youxi_ip on this scripts."
    		else
    			config_and_rsync_single ${1} ${ip}
    		fi
    	fi
    }
    
    #执行主函数
    main $@
  • 相关阅读:
    Entity SQL 初入
    ObjectQuery查询及方法
    Entity Framework 的事务 DbTransaction
    Construct Binary Tree from Preorder and Inorder Traversal
    Reverse Linked List
    Best Time to Buy and Sell Stock
    Remove Duplicates from Sorted Array II
    Reverse Integer
    Implement Stack using Queues
    C++中const限定符的应用
  • 原文地址:https://www.cnblogs.com/wsjhk/p/8260883.html
Copyright © 2011-2022 走看看