肯定有一种简单的方法来做到这一点!
我已经尝试过Linux命令行应用程序,例如sha1sum
和md5sum
,但它们似乎只能计算单个文件的哈希值,并输出每个文件的一个哈希值列表。
我需要为整个文件夹的所有内容(而不仅仅是文件名)生成一个单一的哈希值。
我想做类似于以下的操作:
sha1sum /folder/of/stuff > singlehashvalue
编辑:为了澄清,我的文件分布在目录树的多个层级中,它们并不都位于同一根文件夹中。
肯定有一种简单的方法来做到这一点!
我已经尝试过Linux命令行应用程序,例如sha1sum
和md5sum
,但它们似乎只能计算单个文件的哈希值,并输出每个文件的一个哈希值列表。
我需要为整个文件夹的所有内容(而不仅仅是文件名)生成一个单一的哈希值。
我想做类似于以下的操作:
sha1sum /folder/of/stuff > singlehashvalue
编辑:为了澄清,我的文件分布在目录树的多个层级中,它们并不都位于同一根文件夹中。
一种可能的方法是:
sha1sum path/to/folder/* | sha1sum
如果有整个目录树,最好使用find和xargs。 一个可能的命令是:
find path/to/folder -type f -print0 | sort -z | xargs -0 sha1sum | sha1sum
最后,如果您还需要考虑权限和空目录:
(find path/to/folder -type f -print0 | sort -z | xargs -0 sha1sum;
find path/to/folder \( -type f -o -type d \) -print0 | sort -z | \
xargs -0 stat -c '%n %a') \
| sha1sum
< p >参数< code > stat 会导致它打印文件名,后跟它的八进制权限。两个查找将依次运行,导致磁盘IO量增加一倍,第一个查找所有文件名并对内容进行校验,第二个查找所有文件和目录名称,打印名称和模式。find ./folder -type f -print0 | sort -z | xargs -0 sha1sum | sha1sum
。 - robblespath/to/folder
这一部分没有放置初始的/
的原因。 - Vatine使用类似aide的文件系统入侵检测工具。
对目录进行tar打包并计算哈希值:
tar cvf - /path/to/folder | sha1sum
自己编写代码,例如vatine的一行代码:
find /path/to/folder -type f -print0 | sort -z | xargs -0 sha1sum | sha1sum
如果你只想检查文件夹中是否有内容更改,我推荐使用这个:
ls -alR --full-time /folder/of/stuff | sha1sum
它只会给您ls输出的哈希值,其中包含文件夹、子文件夹、它们的文件、时间戳、大小和权限。几乎所有您需要确定是否发生更改的内容。
请注意,该命令不会为每个文件生成哈希值,但这就是为什么它应该比使用find更快的原因。
tar -C <root-dir> -cf - --sort=name <dir> | sha256sum
如果您不关心访问时间或修改时间,也可以使用类似 --mtime='UTC 2019-01-01'
的方式,确保所有时间戳相同。
通常我们需要添加 --group=0 --owner=0 --numeric-owner
来统一所有者的元数据。
使用 --exclude=PATTERN
强烈建议您始终比较权限。
如果您真的不想比较权限,请使用:
--mode=777
$ echo a > test1/a.txt
$ echo b > test1/b.txt
$ tar -C ./ -cf - --sort=name test1 | sha256sum
e159ca984835cf4e1c9c7e939b7069d39b2fd2aa90460877f68f624458b1c95c -
$ tar -C ./ -cf - --sort=name --mode=777 test1 | sha256sum
ef84fe411fb49bcf7967715b7854075004f1c7a7e4a57d2f3742afa4a54c40de -
$ chmod 444 test1/a.txt
$ tar -C ./ -cf - --sort=name --mode=777 test1 | sha256sum
ef84fe411fb49bcf7967715b7854075004f1c7a7e4a57d2f3742afa4a54c40de -
$ tar -C ./ -cf - --sort=name test1 | sha256sum
9b91430d954abb8a361b01de30f0995fb94a511c8fe1f7177ddcd475c85c65ff -
--sort
选项,确保你使用的是GNU tar。--mode=777
。@lvd - Wang你可以使用 tar -c /path/to/folder | sha1sum
命令。
--mtime
选项,如下所示:tar -c /path/to/folder --mtime="1970-01-01" | sha1sum
。 - Binary Phile如果这是一个Git仓库,你想忽略任何在.gitignore
中的文件,你可以使用以下命令:
git ls-files <your_directory> | xargs sha256sum | cut -d" " -f1 | sha256sum | cut -d" " -f1
这对我来说运作良好。
这就是我在脑海中的想法,任何花费一些时间实际工作的人都会发现其他难点和边界情况。
这里有一个工具,占用内存非常少,可以解决大多数情况,可能有些粗糙但已经非常有帮助。
dtreetrawl
的使用示例和输出。
Usage:
dtreetrawl [OPTION...] "/trawl/me" [path2,...]
Help Options:
-h, --help Show help options
Application Options:
-t, --terse Produce a terse output; parsable.
-j, --json Output as JSON
-d, --delim=: Character or string delimiter/separator for terse output(default ':')
-l, --max-level=N Do not traverse tree beyond N level(s)
--hash Enable hashing(default is MD5).
-c, --checksum=md5 Valid hashing algorithms: md5, sha1, sha256, sha512.
-R, --only-root-hash Output only the root hash. Blank line if --hash is not set
-N, --no-name-hash Exclude path name while calculating the root checksum
-F, --no-content-hash Do not hash the contents of the file
-s, --hash-symlink Include symbolic links' referent name while calculating the root checksum
-e, --hash-dirent Include hash of directory entries while calculating root checksum
一段易于理解的输出:
...
... //clipped
...
/home/lab/linux-4.14-rc8/CREDITS
Base name : CREDITS
Level : 1
Type : regular file
Referent name :
File size : 98443 bytes
I-node number : 290850
No. directory entries : 0
Permission (octal) : 0644
Link count : 1
Ownership : UID=0, GID=0
Preferred I/O block size : 4096 bytes
Blocks allocated : 200
Last status change : Tue, 21 Nov 17 21:28:18 +0530
Last file access : Thu, 28 Dec 17 00:53:27 +0530
Last file modification : Tue, 21 Nov 17 21:28:18 +0530
Hash : 9f0312d130016d103aa5fc9d16a2437e
Stats for /home/lab/linux-4.14-rc8:
Elapsed time : 1.305767 s
Start time : Sun, 07 Jan 18 03:42:39 +0530
Root hash : 434e93111ad6f9335bb4954bc8f4eca4
Hash type : md5
Depth : 8
Total,
size : 66850916 bytes
entries : 12484
directories : 763
regular files : 11715
symlinks : 6
block devices : 0
char devices : 0
sockets : 0
FIFOs/pipes : 0
另外一个实现这个目标的工具:
http://md5deep.sourceforge.net/
它的作用类似于 md5sum,但是还可以递归处理,同时有其他功能。
md5deep -r {direcotory}
cat $FILES | md5sum
确保在计算哈希时文件的顺序相同:
cat $(echo $FILES | sort) | md5sum
但是您的文件列表中不能包含目录。
将多进程和进度条添加到kvantour的答案中
速度提升约30倍(取决于CPU)
100%|██████████████████████████████████| 31378/31378 [03:03<00:00, 171.43file/s]
# to hash without permissions
find . -type f -print0 | sort -z | xargs -P $(nproc --all) -0 sha1sum | tqdm --unit file --total $(find . -type f | wc -l) | sort | awk '{ print $1 }' | sha1sum
# to hash permissions
(find . -type f -print0 | sort -z | xargs -P $(nproc --all) -0 sha1sum | sort | awk '{ print $1 }';
find . \( -type f -o -type d \) -print0 | sort -z | xargs -P $(nproc --all) -0 stat -c '%n %a') | \
sort | sha1sum | awk '{ print $1 }'
请确保已安装tqdm,可通过pip install tqdm
或查看文档进行安装。
awk
将删除文件路径,以便如果父目录或路径不同,则不会影响哈希值。