sha1sum用于目录的目录


33
sha1sum ./path/to/directory/* | sha1sum 

以上内容是作为计算包含文件的目录的sha1sum的一种方式发布的。如果目录包含更多目录,此命令将失败。是否有一种方法可以通用地递归计算目录目录的sha1sum(无需自定义使算法适合所讨论的特定目录)?

Answers:


14

感谢这篇SO帖子 -

find . -type f \( -exec sha1sum "$PWD"/{} \; \) | sha1sum

警告:此代码未经测试!如果错误,请编辑此问题,您可以解决它;我会批准您的修改。


抱歉; 我无法抗拒!;-)递归很有趣。当然有办法了。我现在写一个正确的答案。
allquixotic

3
这不会为不同机器上的完全相同的文件夹生成相同的哈希,因为输出还包含<hash>和<file path>,这些文件路径在不同的机器上不同,并且在不同的机器上导致不同的哈希。正确的行应类似于find . -type f \( -exec sha1sum "$PWD"/{} \; \) | awk '{print $1}' | sort | sha1sum@allquixotic
alper 18'Aug

1
除此之外,文件的哈希应按顺序排列,如果排序顺序在不同的计算机上不同,这也会导致不同的哈希。
alper

40

我通常喜欢“查找| xargs”模式,如下所示:

find ./path/to/directory/ -type f -print0  | xargs -0 sha1sum

如果文件名中有空格,则必须使用“ -print0”和“ -0”。

但是,这与“ find -exec cmd {}”模式非常相似。

在此处查看比较这两种模式的讨论:https : //stackoverflow.com/questions/896808/find-exec-cmd-vs-xargs


您的答案仅返回文件的哈希值。文件夹的哈希值应使用来获取find . -type f -print0 | xargs -0 sha1sum | awk '{print $1}' | sha1sum
alper

5

更新:自从我发布此答复以来已经有好几年了,与此同时,我已经重写并改进了我在这里介绍过的脚本多次。我决定将新脚本重新发布为全新答案。在这一方面,我强烈推荐它。

介绍

我观察到,find命令输出目录中找到的元素的顺序在不同分区的相同目录中有所不同。如果要比较同一目录的哈希,则不必担心,但是如果要确保在复制过程中没有丢失或损坏文件,则需要为排序目录及其元素的内容。例如,Matthew Bohnsack的回答很优雅:

find ./path/to/directory/ -type f -print0  | xargs -0 sha1sum

但是,如果要使用它来比较复制的目录和原始目录,则将输出发送到txt文件,然后使用Kompare或WinMerge或通过简单地获取每个lis的哈希将输出与另一个目录的输出列表进行比较。 。事实是,由于查找工具输出内容的顺序在一个目录之间可能会有所不同,因此Kompare会发出许多差异,因为散列的计算顺序不同。对于小型目录而言,这没什么大不了的,但是如果要处理30000个文件,则很烦人。因此,您需要执行额外的步骤来对输出进行排序,以使比较两个目录之间的哈希列表变得更加容易。

find ./path/to/directory/ -type f -print0  | xargs -0 sha1sum > sha1sum_list_unsorted.txt
sort sha1sum_list_unsorted.txt > sha1sum_list_sorted.txt

这将对输出进行排序,以便在运行差异程序时,具有相同哈希值的文件将位于同一行(前提是没有文件丢失新目录)。

然后到脚本...

这是我写的脚本。它执行与find / xarg答案相同的操作,但是它将在获取sha1sum之前对文件进行排序(将它们保存在同一目录中)。脚本的第一行以递归方式查找目录中的所有文件。下一个按字母顺序对结果进行排序。接下来的两个,获取已排序的内容,并在已排序列表中的文件上附加一个sha1sum和引号,从而创建一个大型shell脚本,一次计算每个文件的哈希值,然后将其输出到content_sha1sum.txt。

#!/bin/bash
find . -type f > content.txt
sort content.txt > content_sorted.txt
awk '{print "sha1sum \""$0}' content_sorted.txt > temp.txt
awk '{print $0"\""}' temp.txt > get_sha1.sh
chmod +x get_sha1.sh
./get_sha1.sh > content_sha1sum.txt
rm content.txt
rm content_sorted.txt
rm temp.txt
rm get_sha1.sh
xdg-open content_sha1sum.txt

希望这可以帮助。


当所有文件名的总长度适合命令行时,通过sort -z--zero-terminated)进行传递比弄乱一堆文件更容易。
安东·萨姆索诺夫

@AntonSamsonov这是一个非常古老的脚本,我当时只是在学习脚本。从那以后,我已经重写了很多次。关于您的评论,排序时零终止是做什么的:我阅读了排序的手册页。他们说零终止将零字节放在行尾而不是换行符。那完成了什么?
thebunnyrules '18

我在这里将脚本的更新发布为单独的答案:superuser.com/questions/458326/…–
thebunnyrules

4

介绍

几年前,我编写并展示了一个脚本(在该线程中),该脚本可以检查当前目录结构中所有单个文件的哈希签名,并将其作为列表输出到文本文件中。

从那时起,我已经对该公式进行了多次完善。我决定在这里重新发布新的和改进的脚本作为单独的答案。它是为sha256写的,但是仍然想要使用sha1的任何人都可以进行简单的搜索,并替换为gedit以将sha256与sha1交换。就个人而言,我已经有两年没有使用sha1了,我也不推荐使用它,因为它已经过时,并且google已经证明了它可以被攻破

这是我的新脚本的作用:

  1. 您可以简单地使用脚本,只需转到要散列的目录并输入:

    sha256rec

    或者,您可以通过执行以下操作从另一个目录调用此脚本:

    sha256rec "/path/to/target/directory/you/want/hash"
  2. 脚本将检测您是否在当前目录中具有写权限。如果这样做,结果将保存在当前目录中。如果您没有写权限,或者当前目录位于只读系统(例如cdrom)中,则结果将保存到当前用户的主目录中。

  3. 脚本将检测在当前用户权限下是否无法访问某些子目录。如果所有内容都是可读的,则不会进行特权提升;如果所有内容都不可读,则将用户的特权提升为root。

  4. 查找用于查找当前目录结构中的所有文件(包括所有子目录)。排序用于确保结果按字母顺序输出。结果列表经过sha256sum,并输出到文本文件。

  5. 自编写旧脚本以来,我采用了一种设计理念,即临时文件是邪恶的,应尽可能避免使用,因为它们会使用户容易受到恶意第三方的监视和篡改。因此,此新脚本中的所有数据都将作为变量进行操作,直到最后一刻为止,结果将以文本文件形式输出。

  6. 结果文件本身被散列,并且路径/散列在终端中输出。我喜欢用一台老式的离线相机为这些哈希值拍照,以确保以后再引用该结果文件时都不会被篡改。

  7. 计数中将忽略旧的结果文件。它使比较结果更加容易。

这是运行我的脚本时终端输出的示例:

kernelcrunch@ubuntu:/usr/src/linux-headers-4.13.0-16-generic$ sha256rec
======================================================================= 
sha256rec:         
=======================================================================        
Current Folder : /usr/src/linux-headers-4.13.0-16-generic   
Target Folder  : /usr/src/linux-headers-4.13.0-16-generic
Output File    : /home/kernelcrunch/000_sha256sum_recurs_linux-headers-4.13.0-16-generic_d_22-04-2018_t_02.17.txt


Seems you're currently in either a Read-Only system or a root owned directory as a regular user. You can find the hash results in your home folder.
f3ddb06212622c375c6bcc11bd629ce38f6c48b7474054ca6f569ded4b4af9d8  /home/kernelcrunch/000_sha256sum_recurs_linux-headers-4.13.0-16-generic_d_22-04-2018_t_02.17.txt
Operation Length: 10 Seconds.
=======================================================================
kernelcrunch@ubuntu:/usr/src/linux-headers-4.13.0-16-generic$ 

以下是可在000_sha256sum_recurs_linux-headers-4.13.0-16-generic_d_22-04-2018_t_02.17.txt中找到的输出摘要:

79c3f378a42bd225642220cc1e4801deb35c046475bb069a96870ad773082805  ./.9491.d
2e336c69cde866c6f01a3495048d0ebc2871dd9c4cb5d647be029e0205d15ce6  ./.config
174f23ff7a7fba897bfb7cf17e9a501bcecacf7ef0c0d5cf030414c1e257d4e3  ./.config.old
389d83f546b250304a9a01bb3072ff79f9d9e380c8a2106cadbf714a872afe33  ./.missing-syscalls.d
035dc77da819101cb9889b4e515023dddd2c953f00d2653b87c6196a6560903e  ./Module.symvers
b28054d7995233e6d003ceb9ed119a0b3354f5ccf77b8d687fc0353ae3c5bfb8  ./arch/x86/include/generated/asm/.syscalls_32.h.cmd
01cf821170e3e6e592e36a96e8628377151c762ac2ee3210c96004bfaef22f5f  ./arch/x86/include/generated/asm/.syscalls_64.h.cmd
111efa83187c58a74a9b0170fd496b497b0682d109a7c240c17e2ffcc734f4f4  ./arch/x86/include/generated/asm/.unistd_32_ia32.h.cmd
fcba4e8abf9e95472c31708555db844ac43c87260fb0ba706b6f519404bf9aba  ./arch/x86/include/generated/asm/.unistd_64_x32.h.cmd
3264438a54cbf7e62b05d38a93c5df8fe4202ac782a5d83ed202cba9eee71139  ./arch/x86/include/generated/asm/.xen-hypercalls.h.cmd
4bd7a45837da7de379b87242efe562ce06bf9d8ab8f636c205bb5ef384c8f759  ./arch/x86/include/generated/asm/clkdev.h
0d96461abd23bbf2da522822948455413a345f9ef8ac7a7f81c6126584b3c964  ./arch/x86/include/generated/asm/dma-contiguous.h
b1a54c24a12ce2c0f283661121974436cdb09ae91822497458072f5f97447c5d  ./arch/x86/include/generated/asm/early_ioremap.h
dd864107295503e102ea339e0fd4496204c697bdd5c1b1a35864dfefe504a990  ./arch/x86/include/generated/asm/mcs_spinlock.h
782ce66804d000472b3c601978fa9bd98dcf3b2750d608c684dc52dd1aa0eb7e  ./arch/x86/include/generated/asm/mm-arch-hooks.h
cd9913197f90cd06e55b19be1e02746655b5e52e388f13ec29032294c2f75897  ./arch/x86/include/generated/asm/syscalls_32.h
758ce35908e8cfeec956f57a206d8064a83a49298e47d47b7e9a7d37b5d96d59  ./arch/x86/include/generated/asm/syscalls_64.h
1147ca3a8443d9ccbdf9cd1f4b9b633f0b77f0559b83ec5e4fa594eadb2548be  ./arch/x86/include/generated/asm/unistd_32_ia32.h
ca5223fbf8f03613a6b000e20eb275d9b8081c8059bc540481a303ce722d42f3  ./arch/x86/include/generated/asm/unistd_64_x32.h
31703052c0d2ab8fe14b4e5dfcc45fcbd5feb5016b0a729b6ba92caa52b069e2  ./arch/x86/include/generated/asm/xen-hypercalls.h
c085ff1b6e9d06faa3fc6a55f69f9065c54098d206827deec7fe0a59d316fc99  ./arch/x86/include/generated/uapi/asm/.unistd_32.h.cmd
7929c16d349845cebb9e303e0ff15f67d924cac42940d0f7271584f1346635fc  ./arch/x86/include/generated/uapi/asm/.unistd_64.h.cmd
9aa492c5a75f5547f8d1dc454bef78189b8f262d1c4b00323a577907f138a63e  ./arch/x86/include/generated/uapi/asm/.unistd_x32.h.cmd
f568e151bbbb5d51fd531604a4a5ca9f17004142cd38ce019f0d5c661d32e36b  ./arch/x86/include/generated/uapi/asm/unistd_32.h
c45cf378498aa06b808bb9ccf5c3c4518e26501667f06c907a385671c60f14ae  ./arch/x86/include/generated/uapi/asm/unistd_64.h
a0088d8d86d7fd96798faa32aa427ed87743d3a0db76605b153d5124845161e2  ./arch/x86/include/generated/uapi/asm/unistd_x32.h
e757eb6420dffa6b24b7aa38ca57e6d6f0bfa7d6f3ea23bbc08789c7e31d15fa  ./arch/x86/kernel/.asm-offsets.s.cmd
f9e703e4f148d370d445c2f8c95f4a1b1ccde28c149cff2db5067c949a63d542  ./arch/x86/kernel/asm-offsets.s
7971fb3e0cc3a3564302b9a3e1ad188d2a00b653189968bbc155d42c70ce6fbf  ./arch/x86/purgatory/.entry64.o.cmd
8352d79fe81d2cf694880f428e283d79fd4b498cea5a425644da25a9641be26b  ./arch/x86/purgatory/.kexec-purgatory.c.cmd
37f3edbee777e955ba3b402098cb6c07500cf9dc7e1d44737f772ac222e6eb3e  ./arch/x86/purgatory/.purgatory.o.cmd
bb8b895cbd2611b69e2f46c2565b4c2e63a85afb56cff946a555f2d277ee99b2  ./arch/x86/purgatory/.purgatory.ro.cmd
bcc2365c9d3d027f1469806eb4f77b0f3ede6eb0855ea0fcd28aa65884046a54  ./arch/x86/purgatory/.setup-x86_64.o.cmd
872229f334fdcc8562e31b9f6581008c1571ac91f12889cd0ff413590585155a  ./arch/x86/purgatory/.sha256.o.cmd
6fb0cbef120aadee282f7bc3b5ea2f912980f16712281f8f7b65901005194422  ./arch/x86/purgatory/.stack.o.cmd
cd1b61063ae3cf45ee0c58b2c55039f3eac5f67a5154726d288b4708c4d43deb  ./arch/x86/purgatory/.string.o.cmd
e5826f0216fd590972bbc8162dd175f87f9f7140c8101505d8ca5849c850ec91  ./arch/x86/purgatory/entry64.o

(像这样继续进行另外7000多行,但您知道了)

安装

  1. 打开终端并输入以下命令:

    cd /usr/bin
    sudo su
    echo '#!/bin/bash'> /usr/bin/sha256rec
    chmod +x /usr/bin/sha256rec
    touch /usr/bin/sha256rec
    nano /usr/bin/sha256rec
  2. 在nano中,使用Shif + Ctrl + v粘贴。按Ctrl-O并按Enter保存。Ctr-X退出。将我的脚本粘贴到那里:

(粘贴在#!/ bin / bash之后)

  #FUNCTIONS OR FUNCTYOU?
  function s_readonly { err=$(date +%s%N); cd "$1"; mkdir $err 2> /tmp/$err; rmdir $err 2>/dev/null; echo $(cat /tmp/$err|grep -i "Read-only file system"|wc -l);shred -n 0 -uz /tmp/$err; }
  function w_denied { echo $(err=$(date +%s%N); cd "$1"; mkdir $err 2> /tmp/$err; rmdir $err 2>/dev/null; cat /tmp/$err|grep -i "Permission denied"|wc -l;shred -n 0 -uz /tmp/$err); }
  function r_denied { echo $(err=$(date +%s%N); cd "$1" >/dev/null 2> /tmp/$err; find . >/dev/null 2>> /tmp/$err; cat /tmp/$err|grep -i "Permission denied"|wc -l;shred -n 0 -uz /tmp/$err); }
  function rando_name { rando=$(echo $(date +%s%N)|sha256sum|awk '{print $1}'); rando=${rando::$(shuf -i 30-77 -n 1)}; echo $rando;}
  function ms0 { ms0=$(($(date +%s%N)/1000000)); }; function mstot { echo $(($(($(date +%s%N)/1000000))-$ms0));}
  function s0 { s0=$(date +%s); }; function stot { echo $(($(date +%s)-$s0));}
  s0

  #CHECK IF A TARGET DIR WAS SPECIFIED (-t= or --target= switch)
  if [ ! -z "$1" ]; then arg1="$1"; arg1_3=${arg1::3}; arg1_9=${arg1::9};fi
  if [ "$arg1_3" = "-t=" -o "$arg1_9" = "--target=" ]; then 
    switch=$(echo $arg1|awk -F '=' '{print $1}')
    switch_chr=$((${#switch}+1))
    target=${arg1:$switch_chr}
    current=$(pwd)
    cd "$target"
    arg1="" #<- cancels the not path in the find line
  else
    current=$(pwd)
    target=$(pwd) 
  fi

  echo -e  "=======================================================================\
    \nsha256rec: \
          \n=======================================================================\
          \nCurrent Folder : $current \
    \nTarget Folder  : $target"

  #GETS DEFAULT_USER, ASSUME'S YOU'RE USER 1000, IF 1000 DOESN'T EXIST SEARCHES 999, THEN 1001, 1002
  default_user=$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)
  if [ -z "$default_user" ]; then default_user=$(awk -v val=999 -F ":" '$3==val{print $1}' /etc/passwd); fi
  if [ -z "$default_user" ]; then default_user=$(awk -v val=1001 -F ":" '$3==val{print $1}' /etc/passwd); fi
  if [ -z "$default_user" ]; then default_user=$(awk -v val=1002 -F ":" '$3==val{print $1}' /etc/passwd); fi

  if [ "$(users | wc -l)" = "1" ]; then USER=$(users|awk '{print $1}'); else USER=$default_user;fi #not perfect but meh...

  #running rando_name in this very specific spot between USER detection and Permission detection, some interfers somehow with detection functions... 
  #the rando function placed underneath the user detection is somehow turning c=$current from the dir path to whatever rando_name puts out.

  #FIGURE OUT WHERE TO PUT HASH LIST
  hash_file="000_sha256sum_recurs_${target##*/}_d_$(date +%d-%m-20%y)_t_$(date +%H.%M).txt"
  if [ $(s_readonly "$current") -gt 0 -o $(w_denied "$current") -gt 0 ]; then if [ "$(whoami)" != root ]; then dest="/home/$(whoami)";echo -e "Output File    : $dest/$hash_file\n\n";echo "Seems you're currently in either a Read-Only system or a root owned directory as a regular user. You can find the hash results in your home folder."; else dest="/home/$USER";echo -e "Output File    : $dest/$hash_file\n\n";echo "Seems you're currently a Read-Only system. You can find the hash results in $USER's home folder.";fi; else dest="$current";echo -e "Output File    : $dest/$hash_file\n\n";echo "Results will be saved here.";fi



  #CAN REGULAR USER ACCESS TARGET DIR? ARE ALL IT'S SUBDIRS READABLE?
  if [ $(r_denied "$target") -gt 0 ]; then sudo=sudo; echo "Some folder were not read-able as a regular user. User elevation will be required.";fi

  #PERFORM RECURSIVE HASHING
  command=$($sudo find . -type f -not -type l -not -path "$arg1"  -not -path "$2"  -not -path "$3" -not -path "$4"  -not -path "$5"  -not -path "$6" -not -path "$7"  -not -path "$8"  -not -path "$9" |grep -v "\./000_sha"|sort|awk "{print \"$sudo sha256sum \\\"\"\$0}"|awk '{print $0"\""}'|tr '\n' ';')
  eval $command > "$dest/$hash_file"

  sha256sum "$dest/$hash_file"
  echo "Operation Length: $(stot) Seconds."
  echo -e  "======================================================================="



  if [ "$target" != "$current" ]; then cd "$current";fi


  exit
  #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  1. 从nano退出时,请确保通过输入以下内容退出提升的状态:

    exit

最后的想法

  1. 仅当您安装了bash时,这才起作用。我已经使用了一些Synthax来进行子字符串操作,但不适用于sh,dash,ksh或zsh。您仍然可以将任何其他Shell用作日常驱动程序,但需要安装bash。

  2. 可以将输出的列表与各种工具进行比较,例如:(在终端中)diff,sdiff(和图形)diff,kdiff,winmerge。

  3. 我的文件根据路径对输出进行排序,以使人类更容易阅读。我注意到sort命令在不同发行版中的工作方式不同。例如,在一个发行版中,大写字母优先于非大写字母,而在另一种中,大写字母则没有。这会影响输出文件的行顺序,并可能使文件难以比较。如果您始终在同一发行版中使用脚本,那么这应该不会出现任何问题,但是如果哈希列表是在两个不同的环境中生成的,则可能不会出现任何问题。通过对哈希文件进行额外的排序,可以很容易地解决此问题,以便使行按哈希而不是路径进行排序:

     cat 000_sha256sum_oldhashlist|sort> ./old
     cat 000_sha256sum_newhashlist|sort> ./new
     sha256sum ./old ./new; diff ./old ./new

一个更强大的shebang行将是#!/usr/bin/env bash-它也会在其他目录中找到Bash,因为例如Bash可能安装在/ usr / bin中而不是/ bin中,同时env总是始终位于/ usr / bin中据我所知。还要注意的是,由于您需要Bash,因此可以使用[[ blah-blah ]]双括号条件表达式,而不是更通用的[ blah-blah ]单括号变量。
安东·萨姆索诺夫

感谢您的指导。我刚看完[[条件。他们看起来真的很有用。
thebunnyrules 18-4-23的

在复制后比较文件以验证完整性的情况下,关于SHA1受到破坏的担忧实际上并不适用。文件在传输过程中被破坏但仍具有相同的SHA1的可能性几乎为零。如果您怀疑攻击者可能有足够的时间来生成具有冲突的SHA1的其他文件,请使用SHA256,但是对于复制文件的典型情况,这比SHA1或MD5显得过大且慢
Dan Dascalescu

您自己的论点可以用来反对自己。如果您担心正常的(与攻击无关的)腐败,那么sha1本身就是过大的杀伤力。使用md5 / crc32可以获得更快的结果。无论哪种情况(篡改检测或损坏),sha1都不适合。就我个人而言,我在这两种情况下都使用了这些哈希列表,并且自从升级到sha256以来没有发现任何可察觉的性能下降,但是我也没有运行大型服务器。就像我在答案中所说的,通过将我的sha256sum命令替换为所需的哈希值,您可以随意使用所需的任何哈希值:sha1sum,md5sum,b2sum,crc32 ...
thebunnyrules

1

这似乎为我工作:

find . \( -not -name . \) -type f -exec cat {} + | sha1sum

编辑:这只会sha1sum目录树中包含的所有文件。如果目录名称已更改,将无法捕获它。也许像:

find . -exec sha1sum {} + 2>&1 | sha1sum

会做到的。虽然与另一个答案大致相同


1

另一个技巧可能是使用tar哈希文件内容和元数据:

tar -cf - ./path/to/directory | sha1sum

太糟糕了,我只有一票
166_MMX

1
这是行不通的。tar包含一些操作系统(如OSX)的时间戳,每次运行sha1sum都会不同。
srossross

@srossross说什么。另外,如果两个主机上的tar版本不同,则输出将不同。
Dan Dascalescu

1

快速,强大且便携式的解决方案

与涉及的其他解决方案不同tar,以下解决方案可在具有标准Unix实用程序的任何计算机上运行,​​并且通过并行化校验和,比所有其他解决方案都快:

find . -type f | xargs -d'\n' -P0 -n1 md5sum | sort -k 2 | md5sum

由于它在末尾使用排序,因此没有实时进度,因此只需运行命令即可。

这是参数的作用:

  • find . -type f 查找当前目录及其子目录中的所有文件
  • xargs -d'\n'将find的输出分成几行(如果您确实希望文件中包含换行符,请照常执行find -print0 | xargs -0
  • -P0 n1md5sum使用机器支持的最大进程数(多核!)在并行进程中运行
  • sort -k 2md5sum输出的第二个字段排序,这是每个文件的完整路径(第一个是MD5)
  • 最终工具将md5sum计算文件校验和列表的校验和,因此您可以在一行上获得整个目录的校验和,可以轻松地在终端窗口之间直观地进行比较

在您说“ MD5已被破坏”之前,请记住您的威胁模型是什么。您是否要确保从其他主机或磁盘复制的文件完好无损?那么MD5绰绰有余,因为文件在传输过程中被破坏但具有相同MD5的机会为零。但是,如果您担心攻击者有时间用冲突的校验和将文件替换为另一个文件,请使用sha256sum。缺点是SHA函数比MD5慢

实时详细进度

最后,如果您确实想查看实时进度,请修改管道以将临时文件用于校验和:

find . -type f | xargs -d\\n -P0 -n1 md5sum | tee /tmp/sums && sort -k 2 /tmp/sums | md5sum

(请注意,移动sort右后find是行不通的,因为xargs -P0并行化md5sum和结果的顺序到达了。)

此版本的命令还允许您区分两个/tmp/sums文件(如果第二个文件在同一台计算机上,请确保重命名),并查看哪些文件不同。


0

我不是在寻找一个包含所有散列信息的巨大文件,而是在寻找一种在树的每个文件夹中制作文件的方法。我从这里的评论中得到了一些启发。我的比这里发布的要复杂一些。我使用文件旋转,但这对于新玩家来说是最简单的。这个版本将用新的覆盖旧的校验和。保留2-3个版本可能会很好,这取决于您运行它的频率和对“深度”的需求。

[user @ host bin] $ cat mkshaindir 
#!/ bin /破折号
cd $ 1
sha512sum *> .sha512sum

[user @ host bin] $查找/ var / tmp -type d -print0 | xargs -0 -i mkshaindir {}

请注意,出于我的目的,mkshaindir是一个单独的组件,因为可能需要我对新文件夹中的文件或最近更改的文件进行哈希处理。如果需要,可以将它们全部合并为一个脚本。

剩下的作为练习留给读者。


0

根据先前的答案

find ./path/to/directory -print0 | LC_ALL=C sort --zero-terminated | tar --create --no-recursion --null --files-from /dev/stdin --file /dev/stdout --verbose --numeric-owner | sha1sum

  • 稳定排序
  • 数字所有者和组ID
  • 详细进度
  • 文件名安全

这在仅包含一个文件的复制目录上不起作用,我怀疑这是因为我在远程主机上运行的tar(1.28)稍旧版本,而在本地主机上运行的是1.29。不幸的是,tar 1.29尚未在Xenial上向后移植
Dan Dascalescu

0

@allquixotic的答案不会在不同的计算机上生成相同的哈希值,这不会帮助我们验证哈希值并保持一致。

以下行find . -type f \( -exec md5sum "$PWD"/{} \; \)返回以下输出:

d41d8cd98f00b204e9800998ecf8427e  /home/helloWorld.c
24811012be8faa36c8f487bbaaadeb71  /home/helloMars.c

因此,路径在不同的机器上会有所不同。awk '{print $1}'将帮助我们获得第一列,该列仅包含文件的哈希。稍后,我们需要对这些哈希进行排序,这些哈希在不同计算机上的顺序可能不同,如果有两个以上的文件,这也可能导致我们具有不同的哈希。


解:

对于Mac:

find ./path/to/directory/ -type f \( -exec md5 -q  "$PWD"/{} \; \) | awk '{print $1}' | sort | md5

对于Linux:

find ./path/to/directory/ -type f \( -exec md5sum "$PWD"/{} \; \) | awk '{print $1}' | sort | md5sum | awk '{print $1}'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.