为何字符串比较失效?MD5哈希明明相等却判定不匹配
问题解决
核心问题
你的脚本存在两个导致比对失败的问题:
md5sum从标准输入读取内容时,输出格式是[哈希值] -(两个空格加横杠),但用echo -n $checksum写入文件时,Bash会把变量里的连续空白符替换成单个空格,导致写入文件的内容变成[哈希值] -(单个空格)。下次读取这个值后,和新生成的带两个空格的哈希字符串比对,自然判定不等——虽然肉眼看哈希值相同,但隐藏的空格数量不一样。ls的输出不稳定,比如不同环境下文件名排序可能变化,或者文件名包含特殊字符,都会导致哈希无意义变化,即便文件夹内容没改。
修复后的脚本
基础版(解决空格比对问题)
#!/bin/bash checksum=$(ls <FOLDER> | md5sum | awk '{print $1}') last_checksum=$(cat CHECKSUM) if [ "$checksum" != "$last_checksum" ]; then echo -n "$checksum" > CHECKSUM echo CHECKSUMS ARE UNEQUAL fi
- 用
awk '{print $1}'只提取纯MD5哈希值,去掉后面的空格和-,避免空白符干扰。 - 给
$checksum加双引号,防止Bash解析空白符。
稳定版(解决文件夹内容检测的可靠性问题)
如果你的需求是检测文件夹内文件内容是否变化,推荐用更稳定的方式生成哈希,避免ls的不确定性:
#!/bin/bash FOLDER="/your/target/folder" CHECKFILE="CHECKSUM" # 递归遍历文件、稳定排序、计算每个文件哈希后汇总生成总哈希 checksum=$(find "$FOLDER" -type f -print0 | sort -z | xargs -0 md5sum | md5sum | awk '{print $1}') # 读取历史哈希(文件不存在则为空) last_checksum=$(< "$CHECKFILE") if [ "$checksum" != "$last_checksum" ]; then echo -n "$checksum" > "$CHECKFILE" echo CHECKSUMS ARE UNEQUAL fi
这个版本的优势:
- 用
find -print0和sort -z处理带特殊字符的文件名(比如含空格、换行的文件名) - 按固定顺序排序文件,避免因排序变化导致哈希无意义变更
- 基于每个文件的内容哈希汇总,真正检测文件内容变化,而非文件名列表变化
内容的提问来源于stack exchange,提问作者adrian n
相关产品推荐
相关产品推荐

