![递归校验和](https://linux22.com/image/851521/%E9%80%92%E5%BD%92%E6%A0%A1%E9%AA%8C%E5%92%8C.png)
我一直使用以下命令行对目录进行递归校验和。它似乎可以完成工作,但作为一个新手,我一直在想,这样做会有什么潜在的问题吗?这个命令是否有可能遗漏文件或造成混乱?
find ./dir/ -type f -exec sha1sum {} \; > files.sha1
答案1
我认为您的方法没有任何问题。您排除了目录,而 find 默认会包含隐藏文件。是的,没问题。
但我会给你提供一个替代方案,因为这就是我所做的:
shopt -s globstar dotglob
sha1sum **
globstar
启用递归匹配**
并dotglob
启用匹配隐藏文件。它们会扩展到所有文件名,sha1sum 可以解析所有文件名。
这种方法的主要问题是它会通过全部文件名被放到sha1sum
一个大堆中。虽然在小负载下这可以稍微快一些,但如果文件名太多,它就会崩溃。我不知道临界点是什么。
答案2
带有 hashlib 和 os.walk 的 Python 脚本
除了使用find
和 之外globstar
,python 还有用于计算哈希值和递归遍历目录树的模块。因此,可以编写一个简单的脚本,如下所示。事实上,这个脚本与我使用的脚本非常相似这个答案但有一个细微的差别。
该脚本假定您想要递归遍历当前工作目录,因此请确保cd
首先到达所需的顶级目录。
我还建议您将其保存在~/bin
目录中并source ~/.bashrc
在使用前运行,因为这样,您只需在命令行上输入脚本的名称即可。
该脚本收集所有文件,包括隐藏文件(文件名以点开头)。
脚本源
#!/usr/bin/env python3
import os
import sys
from hashlib import sha1
def get_sha1sum(file_path):
sha1sum = sha1()
with open(file_path, 'rb') as fd:
data_chunk = fd.read(1024)
while data_chunk:
sha1sum.update(data_chunk)
data_chunk = fd.read(1024)
return str(sha1sum.hexdigest())
def find_files(treeroot):
for dir,subdirs,files in os.walk(treeroot):
for f in files:
full_path = os.path.join(dir,f)
path_sha1sum = get_sha1sum( full_path )
print(path_sha1sum,full_path)
def main():
find_files('.')
if __name__ == '__main__': main()
演示运行
bash-4.3$ cd Wallpapers/
bash-4.3$ recursive_checksum.py
c66af072272d2c516e29832d0a86afa0e8e61d8c ./moon_moon.jpg
37829801c48ea0420414fc78de45adb13e4b117f ./wat.png
6cc3dd2541d00aa5fb8fd6ec703d3c7653ce4708 ./hard_drive_wallpapers/hard-drive.jpg
52fbff84cba6bbbfadc5777c1189ec39aef9176a ./hard_drive_wallpapers/hard-drive5.jpg
5bfe52eb8b31f50dc7bd1b1991dcc1d7260ec65e ./hard_drive_wallpapers/hard-drive4.jpg
f2f85eaa24c8c5b82bbedd55f887ea5fc520ac21 ./hard_drive_wallpapers/hard-drive3.jpg
bcdcf278c176fa93557627a33bedebe4e508e27a ./hard_drive_wallpapers/hard-drive2.jpg