数据同步
#!/usr/bin/env bash
# 颜色定义
readonly COLOR_RED='\033[1;31m'
readonly COLOR_GREEN='\033[1;32m'
readonly COLOR_YELLOW='\033[1;33m'
readonly COLOR_BLUE='\033[1;34m'
readonly COLOR_MAGENTA='\033[1;35m'
readonly COLOR_CYAN='\033[1;36m'
readonly COLOR_RESET='\033[0m'
# 日志函数
log_error() { echo -e "${COLOR_RED}[ERROR] $1${COLOR_RESET}" >&2; }
log_warn() { echo -e "${COLOR_YELLOW}[WARN] $1${COLOR_RESET}"; }
log_info() { echo -e "${COLOR_BLUE}[INFO] $1${COLOR_RESET}"; }
log_success() { echo -e "${COLOR_GREEN}[SUCCESS] $1${COLOR_RESET}"; }
check_directory() {
local dir="$1"
local create_if_not_exist="$2" # "true" 或 "false"
# 如果目录为空,返回失败
if [[ -z "$dir" ]]; then
return 1
fi
# 检查目录是否存在
if [[ ! -d "$dir" ]]; then
if [[ "$create_if_not_exist" == "true" ]]; then
# 尝试创建目录
if mkdir -p "$dir" 2>/dev/null; then
log_info "创建目录: $dir"
return 0
else
log_error "无法创建目录: $dir"
return 1
fi
else
log_error "目录不存在: $dir"
return 1
fi
fi
# 检查目录是否可写
if [[ ! -w "$dir" ]]; then
log_error "目录不可写: $dir"
return 1
fi
return 0
}
zdh(){
while true;do
read -r -p "目的地主机IP: " IPADDRS
if [[ "$IPADDRS" =~ ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]]; then
break
else
log_error "请输入正确IP地址!"
fi
done
while true;do
read -r -p "目的地主机ssh端口: " SSHPORTS
if [[ "$SSHPORTS" =~ ^[0-9]+$ ]] && (( SSHPORTS >= 1 && SSHPORTS <= 65535 )); then
break
else
log_error "请输入正确端口!"
fi
done
while true;do
read -r -p "${IPADDRS} 机器是否已配置免密登录? y/n: " SSHKEYGEN
if [ "${SSHKEYGEN}" == "y" ];then
if ssh -o BatchMode=yes -o ConnectTimeout="3" -o StrictHostKeyChecking=no -p "${SSHPORTS}" "${IPADDRS}" "echo 'SSH免密登录测试成功'" 2>/dev/null; then
log_success "SSH免密登录已配置"
break
else
log_warn "SSH免密登录未配置"
log_info "ssh免密配置脚本下载: wget https://packages.emal.cc/package/softinstall/doc/sh/update_keygen.sh"
log_info '请在备份主机生成公钥和私钥,命令: ssh-keygen -t rsa -b 4096 -o -a 100 -C "comment"'
fi
elif [ "${SSHKEYGEN}" == "n" ];then
log_warn "请先配置免密登录!"
log_info "ssh免密配置脚本下载: wget https://packages.emal.cc/package/softinstall/doc/sh/update_keygen.sh"
log_info '请在备份主机生成公钥和私钥,命令: ssh-keygen -t rsa -b 4096 -o -a 100 -C "comment"'
exit 0
else
log_error "请输入正确的值 y/n"
fi
done
while true; do
read -r -p "备份主机目录: " SRCDATA
# 检查目录是否存在
if check_directory "$SRCDATA" "false"; then
# 检查目录是否为空
if [[ -z "$(ls -A "$SRCDATA" 2>/dev/null)" ]]; then
log_warn "目录为空: $SRCDATA"
read -r -p "是否继续使用空目录? [y/n]: " confirm
if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then
continue
fi
fi
break
else
log_error "请重新输入有效的目录路径"
fi
done
while true; do
read -r -p "目的地主机目录: " DESTDATA
# 尝试在远程主机上创建目录
log_info "检查远程主机目录..."
if [[ "${SSHKEYGEN,,}" =~ ^(y|yes)$ ]]; then
if ssh -p "$SSHPORTS" "$IPADDRS" \
"mkdir -p '$DESTDATA' && test -w '$DESTDATA'" 2>/dev/null; then
log_success "远程目录可用: $DESTDATA"
break
else
log_error "无法访问或创建远程目录: $DESTDATA"
fi
else
# 如果不支持免密登录,只做基本验证
if [[ -n "$DESTDATA" ]]; then
log_warn "由于未配置SSH免密登录,无法验证远程目录,请确保目录存在且可写"
break
else
log_error "目录不能为空"
fi
fi
done
while true; do
read -r -p "备份主机日志存放目录: " LOGSDIR
if [ ! -f ${LOGSDIR} ];then
touch ${LOGSDIR} > /dev/null 2>&1
if [ $? -eq 0 ];then
log_success "${LOGSDIR} 日志文件已创建!"
break
else
log_error "请正确得输入文件名称,不要输入不存在得路径!"
fi
else
log_info "${LOGSDIR} 日志文件已创建!"
read -r -p "是否使用已存在文件做为日志文件? y/n: " YESS
if [ "${YESS}" == "y" ];then
log_info "日志文件路径: ${LOGSDIR}"
break
elif [ "${YESS}" == "n" ];then
continue
else
continue
fi
fi
done
}
sd(){
# demo=1时,跳过下载软件包
demo=1
if [ "${demo}" == "1" ];then
echo "相关软件包下载完成"
else
yum -y install rsync inotify-tools > /dev/null 2>&1
if [ $? -eq 0 ];then
echo "相关软件包下载完成"
else
echo "相关软件包下载失败"
exit 1
fi
fi
count=0
while [ $count -lt 1 ]; do
HOSTIP=$(hostname -I |awk '{print $1}')
sleep 2
echo "#####################################################" >> ${LOGSDIR}
echo $(date '+%c') >> ${LOGSDIR}
inotifywait -r -e modify,create,delete,move ${SRCDATA} >> ${LOGSDIR} &
rsync -avz -e "ssh -p ${SSHPORTS}" ${SRCDATA} --exclude='/data/docker' --exclude='docker/' --exclude='**/containers/**' --exclude='*.log' --exclude='*-json.log' root@${IPADDRS}:${DESTDATA}/ >> ${LOGSDIR} &
echo " " >> ${LOGSDIR}
# 查看日志大小
dus=$(ls -lh ${LOGSDIR} |awk '{print $5}'|grep G|awk -F'M' '{print $1}')
b=2
# 判断日志如果大于2个G,那么就删除日志
dateus=$(awk -v num1=${dus} -v num2=${b} 'BEGIN{print(num1>num2)?"0":"1"}')
echo ${dateus}
if [ ${dateus} -eq 0 ];then
echo "" > ${LOGSDIR}
else
exit 0
fi
count=$((count + 1))
done > /dev/null 2>&1
}
main(){
zdh
sd
}
main
评论 (0)