开发工具

以下是一个用于检测两台服务器指定目录文件一致性的Shell脚本,支持文件内容(MD5)、大小、修改时间等属性对比,并提供差异报告:

#!/bin/bash
# 文件一致性检测脚本
# 用法:./check_filesync.sh <本地目录> <远程用户@主机> <远程目录>

LOCAL_DIR="$1"
REMOTE="$2"
REMOTE_DIR="$3"
LOG_FILE="/var/log/file_consistency.log"
TMP_DIR="/tmp/file_check_$(date +%s)"
MD5_SCRIPT="/tmp/gen_md5list.sh"

# 创建临时目录
mkdir -p "$TMP_DIR"

# 生成MD5列表的脚本(用于本地和远程执行)
cat > "$MD5_SCRIPT" <<'EOF'
#!/bin/bash
DIR="$1"
OUTPUT="$2"
find "$DIR" -type f -exec md5sum {} + | sort > "$OUTPUT"
find "$DIR" -type d -printf "%P\n" | sort > "${OUTPUT}.dir"
stat -c "%n|%s|%Y|%U|%G|%A" "$DIR"/* > "${OUTPUT}.stat"
EOF
chmod +x "$MD5_SCRIPT"

# 在本地生成检查文件
LOCAL_MD5="${TMP_DIR}/local.md5"
"$MD5_SCRIPT" "$LOCAL_DIR" "$LOCAL_MD5"

# 在远程生成检查文件
REMOTE_MD5="${TMP_DIR}/remote.md5"
ssh "$REMOTE" "$MD5_SCRIPT" "$REMOTE_DIR" "$REMOTE_MD5"
scp "${REMOTE}:${REMOTE_MD5}"* "$TMP_DIR"

# 对比文件差异
compare_files() {
    echo "===== 文件内容差异 ====="
    diff -u "$LOCAL_MD5" "$REMOTE_MD5" | grep '^[-+][^-+]'
    
    echo -e "\n===== 目录结构差异 ====="
    diff -u "${LOCAL_MD5}.dir" "${REMOTE_MD5}.dir" | grep '^[-+][^-+]'
    
    echo -e "\n===== 文件属性差异 ====="
    awk -F'|' 'NR==FNR{a[$1]=$0;next} {if(a[$1]){split(a[$1],b,"|");if($2!=b[2]||$3!=b[3]||$4!=b[4]||$5!=b[5]||$6!=b[6]) print "本地:"a[$1]"\n远程:"$0}}' \
    "${LOCAL_MD5}.stat" "${REMOTE_MD5}.stat"
}

# 生成报告
generate_report() {
    echo "检测时间: $(date '+%Y-%m-%d %H:%M:%S')" | tee -a "$LOG_FILE"
    echo "本地目录: $LOCAL_DIR" | tee -a "$LOG_FILE"
    echo "远程目录: $REMOTE:$REMOTE_DIR" | tee -a "$LOG_FILE"
    compare_files | tee -a "$LOG_FILE"
    echo -e "\n" | tee -a "$LOG_FILE"
}

# 清理临时文件
cleanup() {
    rm -rf "$TMP_DIR"
    ssh "$REMOTE" "rm -f ${REMOTE_MD5}*"
}

# 主流程
generate_report
cleanup


使用说明

1、运行脚本

# 示例:检查本地的/data和远程服务器192.168.1.100的/backup/data
./check_filesync.sh /data root@192.168.1.100 /backup/data


2、查看日志

tail -f /var/log/file_consistency.log


功能特性

1、多维度对比

文件内容:通过MD5校验和验证

目录结构:对比子目录是否存在

文件属性:对比大小、修改时间、权限、属主


2、差异报告示例

检测时间:2023-10-05 15:30:00
本地目录: /data
远程目录: root@192.168.1.100:/backup/data

===== 文件内容差异 =====
-9e107d4d372bc4cbd4dfb670468c9004  /data/file1.txt
+6f5902ac237024bdd0c176cb93063dc4  /data/file1.txt

===== 目录结构差异 =====
+subdir3

===== 文件属性差异 =====
本地:file2.txt|1024|1662345678|root|root|-rw-r--r--
远程:file2.txt|2048|1662345678|root|root|-rw-r--r--


3、自动清理

脚本执行后自动删除临时文件,保留日志到/var/log/file_consistency.log



进阶配置

1、SSH免密登录

# 生成密钥对
ssh-keygen -t rsa

# 复制公钥到远程服务器
ssh-copy-id root@192.168.1.100


2、定时检测(Cron)

# 每天凌晨2点执行检测
0 2 * * * /root/check_filesync.sh /data root@192.168.1.100 /backup/data


3、邮件告警

在脚本末尾添加:

if [ $(grep -c '^[-+]' "$LOG_FILE") -gt 0 ]; then
    mail -s "文件一致性报警" admin@example.com < "$LOG_FILE"
fi



性能优化

1、并行计算MD5

# 修改MD5生成脚本部分
find "$DIR" -type f -print0 | xargs -0 -P4 md5sum


2、增量对比

保存上一次的MD5记录,仅对比变化部分:

LAST_MD5="/var/last_check.md5"
[ -f "$LAST_MD5" ] && diff "$LAST_MD5" "$CURRENT_MD5"
cp "$CURRENT_MD5" "$LAST_MD5"



注意事项

1、文件系统差异

远程服务器使用不同文件系统(如NTFS)可能导致权限对比不准确


2、符号链接处理

当前脚本跳过符号链接,如需跟踪添加 -L 参数:

find -L "$DIR" -type f  # 跟随符号链接


3、大文件优化

对于超大文件(>10GB),建议改用快速校验方式:

checksum() {
    file="$1"
    stat -c "%s|%Y" "$file"
    dd if="$file" bs=1M count=100 2>/dev/null | md5sum
}


通过该脚本,您可以快速定位文件同步问题,确保关键数据的一致性。建议根据实际需求调整对比粒度和告警策略。