rsync-inotify

元气满满
2026-02-11 / 0 评论 / 0 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2026年03月12日,已超过229天没有更新,若内容或图片失效,请留言反馈。

数据同步

#!/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

评论 (0)

取消