我需要创建一个目录内(包括所有子目录)文件的校验和列表。
我尝试执行的命令如下:
sha256sum -b *
用法:
-b = 以二进制读取。 * = 指定您必须验证所有文件扩展名。
使用该命令我得到以下输出:
sha256sum:test0:是一个目录e3d748fdf10adca15c96d77a38aa0447fa87af9c297cb0b75e314cc313367daf *test1.txtdb0c7a354881fe2dd1b45642a68f6a971c7421e8fdffe56ffa7c740111e07274 *test2.txt
您不应该报告 test0 是一个目录,还应该生成内容的校验和。
你建议-b
在任何类型的文件中都使用它吗?在什么情况下应该-t
使用?
是否可以过滤我想在验证中忽略的文件类型,而不必添加我想要允许的所有文件?我应该执行什么命令?
我寻求帮助但没有找到任何相关内容。
答案1
您可以使用find
查找目录树中的所有文件,然后让其运行sha256sum
。以下命令行将为当前目录及其子目录中的文件创建校验和。
find . -type f -exec sha256sum {} \;
我不使用选项-b
和-t
,但如果您愿意,您可以-b
对所有文件使用。我注意到的唯一区别是每个文件名前面的星号。
答案2
总结
cd /path/to/working/directory
sha256sum <(find . -type f -exec sha256sum {} \; | sort)
介绍
find
对上述问题的更完整的回答,它解决了在不同系统上以不同顺序“查找”文件的问题。
通过管道输出到文件,与...进行比较diff
首先,你可能希望将输出通过管道传输到文件以便与 diff 进行比较。为此,你可以使用
find . -type f -exec sha256sum {} \; > file1.lst
然后在你的其他系统上
find . -type f -exec sha256sum {} \; > file2.lst
rsync file2.lst user@host:/home/user/file2.lst
ssh user@host
diff file1.lst file2.lst # might not match due to order
find
通过管道修复找到的文件的顺序sort
在这里我假设您正在做一些与我要求的类似的事情 - 通过网络将文件从一个系统复制到另一个系统并验证这些文件的完整性。
我发现,find
即使两种情况下的操作系统都是“Debian”,查找文件的顺序在两个系统之间也会有所不同。
因此,需要对文本文件中的输出进行排序。
sort file1.lst > file1sorted.lst
sort file2.lst > file2sorted.lst
diff file1.lst file2.lst # bad
diff file1sorted.lst file2sorted.lst # ok
您可以在一行中完成find
所有操作sort
,同时将输出重定向到文件。
find . -type f -exec sha256sum {} \; | sort > file1.lst
其他 sha/md5 校验和
您可能希望提高 shasumming 的级别。要使用 512 位版本,只需执行以下操作;
find . -type f -exec sha512sum {} \; | sort > file1.lst
或者,256 位可能对你正在做的事情来说有点过分,所以
find . -type f -exec md5sum {} \; | sort > file1.lst
完整的一行命令,用于比较两个目录和 1 个 shasum 输出
现在,如果您有许多文件并且不想将输出保存到文件中,您可以简单地对输出进行 shasum。为此,请使用
sha256sum <(find . -type -f -exec sha256sum {} \; | sort)
在计算最终结果之前,需要使用管道 to 来sort
确保输出已排序sha256sum
。如果没有这个,如果find
以不同的顺序找到文件,尽管每个文件的 shasum 都是正确的,但整体 shasum 将取决于顺序。
与差异输出和所用路径相关的问题
你可能有一些看起来像的路径
/A/B/C/*
其中 * 是您想要 shasum 的子目录和文件。如果A/B/C
有一个或多个目录仅包含 1 个子文件夹,您可能会意外地在错误的目录中运行 shasum 命令,从而导致以下结果
sort1.txt
sha256sum1 ./A/B/C/file1
sort2.txt
sha256sum2 ./B/C/file1
即使sha256sum
= sha256sum2
diff 也会说文件不同。(因为它们是由于路径中不同的基目录造成的。)
下面是一个简短的 python3 代码,用于逐行检查总和,从而解决了这个问题。
#!/usr/bin/env python3
file1_name = "sort1.txt"
file2_name = "sort2.txt"
file1 = open(file1_name, 'r')
file2 = open(file2_name, 'r')
file1_lines = file1.readlines();
file2_lines = file2.readlines();
if(len(file1_lines) == len(file2_lines)):
print("line numbers ok")
for i in range(len(file1_lines)):
line1 = file1_lines[i]
line2 = file2_lines[i]
line1_split = line1.split(' ')
line2_split = line2.split(' ')
shasum1 = line1_split[0]
shasum2 = line2_split[0]
if(shasum1 != shasum2):
print("shasum error: ", line1)
else:
print("Error: file ", file1_name, " number of lines != ", file2_name, " number of lines")
print("done")
我最初想编写一个 shell 脚本来执行此操作,但是我对如何执行此操作感到无聊,因此又回到了 python。
这让我想到,除了 find 命令之外,实际上编写一个 python 代码来完成整个事情会更容易。
答案3
回答晚了,但为了记录的目的......
其他答案建议sha256sum
通过find
选项调用-exec
。这样做的效果是sha256sum
每个文件都调用一次,这对操作系统来说是一笔不小的开销。
更有效的解决方案是通过管道将结果转换find
为命令行参数xargs
并sha256sum
以此方式调用。如果行太多,则xargs
运行一次或大批量运行。sha256sum
find /path/to/your/dir -type f | xargs sha256sum -b
如果你的文件名中有空格,请使用-print0
标志 infind
和-0
标志 inxargs
来终止字符串\0
find /path/to/your/dir -type f -print0 | xargs -0 sha256sum -b
答案4
简短回答:sha256deep
现在把这个常见问题作为最相关的答案之一,感觉很不对。sha*deep|md5deep 已经存在多年了,已经移至哈希深度几年前的软件包,并且一直得到维护,因为...sha256sum 的功能范围非常有限。
另一个注意事项:
我用了CFV过去曾用于此类任务,但它已从 Ubuntu 中删除,并且是最新找到愿意将其移植到 Python3 的新维护者的项目之一。在这里找到这个问题和许多答案,但也意识到 pipx 存在,就跳回 CFV。
# Install pipx
python3 -m pip install --user pipx
# Install CFV
pipx install cfv
# Hash the current directory recursively and create a file containing the
# hashes name like the directory
cfv -Crrt sha256
是否可以过滤我想在验证中忽略的文件类型,而不必添加我想要允许的所有文件?我应该执行什么命令?
这时候 find 就派上用场了,它可以创建你想要哈希的文件列表。你可以尝试使用find
and--exclude
直到输出符合你的需要,然后将 find 的输出重定向到一个文件并运行cfv -Crrt sha256 -f file_list