Ubuntu 24.04中sha256sum对同一文件返回不同哈希的原因排查
问题背景
在Ubuntu 24.04系统中,一个约10G的文件somefile=.7z自创建后未被修改,但多次执行sha256sum时返回过四种不同的哈希值,后续结果趋于稳定。关键操作日志如下:
$ for i in *.7z; do sha256sum $i; done ... a5a887bd0c9e9ed03a1a7851c2b6216ce77284c5d8fd326c008426475d39c3b8 somefile=.7z ... $ pv somefile=.7z | sha256sum ... f62423e10e3a629fe07a5d4d3212942af55541cc1d7b4498a1ca2d97aafdb9c3 - $ sha256sum somefile=.7z f62423e10e3a629fe07a5d4d3212942af55541cc1d7b4498a1ca2d97aafdb9c3 somefile=.7z $ for i in *.7z; do sha256sum $i; done ... f62423e10e3a629fe07a5d4d3212942af55541cc1d7b4498a1ca2d97aafdb9c3 somefile=.7z
用户已排除循环调用方式、文件体积、特殊文件名、外部硬盘挂载等因素,后续更新发现:首次得到的哈希值与已被替换的同名旧文件的sha1sum一致,怀疑存在按文件名缓存的bug。
可能的忽略场景
系统页缓存未及时刷新
文件被替换后(比如用新文件覆盖旧文件),系统的页缓存可能还保留着旧文件的数据。对于10G的大文件,缓存刷新存在延迟,首次读取时直接加载了缓存里的旧数据,后续读取才同步到磁盘上的新文件内容。工具/库的文件名缓存失效延迟
部分系统工具或底层库可能会缓存文件名对应的文件数据或inode信息,当旧文件被删除替换后,缓存没有立即失效,导致首次sha256sum调用读取了缓存中的旧文件数据,后续缓存过期后才读取到正确的新文件。文件替换操作未完全落地
即使你认为文件在循环前已被替换,但如果替换是通过cp大文件后改名覆盖,可能存在磁盘缓存未同步的情况——文件数据还在内存缓存里,没完全写到磁盘上。首次循环读取时,文件处于未完全落地的状态,后续磁盘缓存同步后才读到完整的新文件。文件系统目录条目缓存问题
首次执行for i in *.7z时,shell的通配符展开可能读取了缓存的目录条目,匹配到了旧文件的残留引用(比如未彻底清理的inode),后续再次执行循环时,目录条目缓存更新,才匹配到正确的新文件。磁盘IO临时异常
如果文件存放在外部硬盘,可能出现临时IO错误、磁盘缓存不一致的情况,导致读取到的数据出错。不过这种情况通常会伴随dmesg里的磁盘报错,且哈希值不会稳定到固定结果,可以检查系统日志确认。
内容的提问来源于stack exchange,提问作者Sylvain Hubert

