Bash使用sha256sum比对文件哈希时条件判断不生效问题
Bash脚本SHA256哈希比对判断失效排查
问题表现
执行比对命令bash check-256.sh cal.sh 2cal.sh,终端打印的两个文件哈希值前缀完全一致,但脚本最终输出Fail,未按预期输出Pass。
运行输出如下:
└──╼ $bash check-256.sh cal.sh 2cal.sh ea8f4b5acdeb26015661ee27c9000af97691a0fd715be94b2b3eda6a3d02c789 cal.sh ea8f4b5acdeb26015661ee27c9000af97691a0fd715be94b2b3eda6a3d02c789 2cal.sh Fail
原问题脚本代码:
#!/bin/bash First_file=$(sha256sum $1) Second_file=$(sha256sum $2) echo "$First_file" echo "$Second_file" [ "$First_file" == "$Second_file" ] && echo "Pass" || echo "Fail"
故障根因
sha256sum默认输出格式为64位哈希值 + 两个空格 + 被计算的文件名,你存入变量的是整条输出内容:第一个变量末尾带文件名cal.sh,第二个变量末尾带文件名2cal.sh,两个字符串从文件名位置开始就存在差异,相等判断必然不成立。肉眼查看输出时很容易只关注前面的哈希串,忽略末尾的文件名差异。
另外原脚本还存在两个兼容性隐患:
- 位置变量
$1/$2未加双引号包裹,当文件名包含空格或特殊字符时会出现参数拆分错误 [ ]结构中使用双等号==做字符串比较属于Bash拓展语法,不符合POSIX标准,在其他Shell环境下可能执行异常,标准写法为单等号=
修复方案
方案1:截取纯哈希值做比对
通过awk提取sha256sum输出的第一个字段(即纯哈希部分),丢弃后面的文件名再做比较,和原有脚本逻辑最贴合,修复后代码如下:
#!/bin/bash First_file=$(sha256sum "$1" | awk '{print $1}') Second_file=$(sha256sum "$2" | awk '{print $1}') echo "$First_file $1" echo "$Second_file $2" [ "$First_file" = "$Second_file" ] && echo "Pass" || echo "Fail"
方案2:使用sha256sum原生校验能力
不需要手动截取字符串比对,直接调用sha256sum自带的-c校验参数,稳定性更高:
#!/bin/bash # 生成临时校验文件 sha256sum "$1" > .tmp_hash_check # 提取第二个文件的哈希值,替换校验文件中的文件名字段做比对 Second_hash=$(sha256sum "$2" | awk '{print $1}') sed -i "s/$1/$2/" .tmp_hash_check sed -i "s/^[a-f0-9]\{64\}/$Second_hash/" .tmp_hash_check # 执行校验,--status参数表示不打印冗余输出,仅通过返回值标识结果 sha256sum -c --status .tmp_hash_check && echo "Pass" || echo "Fail" # 清理临时文件 rm .tmp_hash_check
内容的提问来源于stack exchange,提问作者0xrash
相关产品推荐
相关产品推荐

