ディレクトリのディレクトリのsha1sum


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

上記は、ファイルを含むディレクトリのsha1sumを計算する方法として投稿されました。ディレクトリにさらにディレクトリが含まれている場合、このコマンドは失敗します。ディレクトリのディレクトリのsha1sumを普遍的に再帰的に計算する方法はありますか(問題の特定のディレクトリにアルゴリズムをカスタム適合させずに)?

回答:


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
アルパース

1
これに加えて、ファイルのハッシュは順序付けられている必要があります。これは、マシンごとにソート順が異なる場合にも、異なるハッシュを発生させます。
-alper

40

私は通常、次のように「find | xargs」パターンが好きです。

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

ファイル名にスペースがある場合は、「-print0」と「-0」を使用する必要があります。

ただし、これは「find -exec cmd {}」パターンに非常に似ています。

こちらの2つのパターンを比較した説明をご覧ください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個のファイルを扱う場合は非常に迷惑です。したがって、出力を並べ替える追加の手順を実行して、2つのディレクトリ間でハッシュリストを比較しやすくします。

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を取得する前にファイルを並べ替えます(同じディレクトリに保存します)。スクリプトの最初の行は、ディレクトリ内のすべてのファイルを再帰的に検索します。次は、結果をアルファベット順に並べ替えます。次の2つは、ソートされたコンテンツを取得し、ソートされたリスト内のファイルにsha1sumと引用符を追加して、各ファイルのハッシュを一度に1つずつ計算して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

私はここで別々の答えとして、このスクリプトにアップデートを掲載しました:superuser.com/questions/458326/...は
thebunnyrules

4

前書き

数年前、私は(このスレッドで)現在のディレクトリ構造内のすべての個々のファイルのハッシュ署名をチェックし、それをテキストファイルのリストとして出力できるスクリプトを書いて提示しました。

それ以来、私はこの式を何度も改良してきました。ここで、新しい改善されたスクリプトを別の回答として再投稿することにしました。これはsha256向けに書かれていますが、まだsha1を使用したい人は誰でもgeditで簡単な検索と置換を行い、sha256をsha1と交換できます。個人的には、私は2年ほどsha1を使用していません。陳腐化しており、Googleがどのように侵害されるかを実証しているのでお勧めしません。

新しいスクリプトの機能は次のとおりです。

  1. ハッシュするディレクトリに移動して入力するだけで、スクリプトを使用できます。

    sha256rec

    または、次のようにして別のディレクトリからこのスクリプトを呼び出すことができます。

    sha256rec "/path/to/target/directory/you/want/hash"
  2. スクリプトは、現在のディレクトリに書き込み権限があるかどうかを検出します。その場合、結果は現在のディレクトリに保存されます。書き込み権限がない場合、または現在のディレクトリが読み取り専用システム(cdromなど)にある場合、結果は現在のユーザーのホームディレクトリに保存されます。

  3. スクリプトは、サブディレクトリの一部が現在のユーザー特権でアクセスできないかどうかを検出します。すべてが読み取り可能である場合、特権の昇格は行われません。読み取り可能でない場合、ユーザーの特権はルートに昇格されます。

  4. Findは、現在のディレクトリ構造内のすべてのファイル(すべてのサブディレクトリを含む)を検索するために使用されます。ソートは、結果がアルファベット順に出力されるようにするために使用されます。結果のリストはsha256sumを経て、テキストファイルに出力されます。

  5. 古いスクリプトを書いて以来、私は一時ファイルは悪であり、悪意のある第三者によるoping索や改ざんをユーザーに許しているため、可能な限り避けるべきであるという設計哲学を採用しました。そのため、この新しいスクリプトのすべてのデータは、結果がテキストファイルとして出力される最後の最後まで変数として操作されます。

  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がインストールされている場合にのみ機能します。私は、sh、dash、ksh、またはzshで動作しない部分文字列操作にいくつかのシンタックスを使用しました。毎日のドライバーとして他のシェルを使用できますが、bashをインストールする必要があります。

  2. 出力されたリストは、(端末で)diff、sdiff(およびグラフィカル)Diffuse、kdiff、winmergeなどのさまざまなツールと比較できます。

  3. 私のファイルは、人間が読みやすいように、パスに基づいて出力を並べ替えます。異なるディストリビューション間でsortコマンドの動作が異なることに気付きました。たとえば、あるディストリビューションでは大文字が大文字以外の文字より優先され、別の文字では大文字ではありませんでした。これは、出力ファイルの行順序に影響し、ファイルの比較が困難になる可能性があります。同じディストリビューションで常にスクリプトを使用している場合は問題ありませんが、ハッシュリストが2つの異なる環境で生成された場合は問題ありません。これは、行をパスではなくハッシュで並べ替えるように、ハッシュファイルを追加の時間で並べ替えることで簡単に修正できます。

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

より堅牢なシェバング行は次のようになり#!/usr/bin/env bash-後者は内に設置することができるので、それは、同様に他のディレクトリでバッシュを見つけるの/ usr / binにではなく/ binに、例えば、一方のenvが中になる傾向は/ usr / binにすべての回で私が気づいた限りでは。また、Bashが必要なため[[ blah-blah ]]、より汎用的な[ blah-blah ]単一ブラケットのバリアントではなく、二重ブラケットの条件式を使用できることにも注意してください。
アントンサムソノフ

ポインタをありがとう。[[条件式の検索を終了しました。彼らは本当に便利に見えます。
thebunnyrules

SHA1が侵害されているという懸念は、コピー後にファイルを比較して整合性を検証する場合には実際には当てはまりません。転送中にファイルが破損する可能性はありますが、同じSHA1を保持している可能性はほとんどありません。攻撃者が、SHA1が衝突する別のファイルを生成するのに十分な時間があると思われる場合は、SHA256を使用しますが、ファイルをコピーする一般的なケースでは、やり過ぎでSHA1またはMD5よりも低速です
ダンダスカレスク

あなた自身の引数はそれ自体に対して使用することができます。通常の(攻撃に関連しない)破損が懸念される場合、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

私は唯一の1票持っていることをあまりにも悪い
166_MMX

1
これは動作しません。tarには一部のOS(OSXなど)のタイムスタンプが含まれ、sha1sumは実行ごとに異なります。
srossross

@srossrossが言ったこと。さらに、2つのホストに異なるバージョンのtarがある場合、出力は異なります。
ダンダスカレスク

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出力の2番目のフィールドでソートします。これは各ファイルへのフルパスです(最初のフィールドはMD5です)
  • 最終版md5sumでは、ファイルのチェックサムのリストのチェックサムを計算するため、ディレクトリ全体のチェックサムを1行で取得できます。これは、ターミナルウィンドウ全体で視覚的に簡単に比較できます。

「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、結果が順不同で到着する可能性があるためです。)

このバージョンのコマンドを使用すると、2つのファイルを比較/tmp/sums(同じマシン上にある場合は2番目のファイルの名前を変更してください)、どのファイルが異なるかを確認できます。


0

ハッシュ化された情報のすべてを含む1つの巨大なファイルではなく、ツリーの各フォルダーにファイルを作成する方法を探していました。ここでのコメントからインスピレーションを得ました。鉱山はここに掲載されているものよりも少し複雑です。私はファイルローテーションを使用しますが、これは新しいプレーヤーにとっては最も複雑ではありません。このバージョンでは、古いチェックサムが新しいチェックサムで上書きされます。実行頻度と「深さ」の必要性に応じて、2〜3つのバージョンを保持しておくとよいでしょう。

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

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

私の目的では、mkshaindirは別のコンポーネントであることに注意してください。これは、新しいフォルダー内のファイル、または最近変更されたファイルのハッシュを作成する必要があるためです。必要に応じて、これらをすべて1つのスクリプトに結合できます。

残りは読者のための演習として残されています。


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
  • 詳細な進捗
  • ファイル名セーフ

これは、ファイルが1つだけ含まれるコピーされたディレクトリでは機能しませんでした。ローカルホストの1.29に対して、リモートホストで少し古いバージョンのtar(1.28)を実行していたためだと思います。残念ながら、tar 1.29はXenialにバックポートされていません。
ダンダスカレスク

0

@allquixoticの答えは、異なるマシンで同じハッシュを生成しないため、一貫したハッシュを検証して保持するのに役立ちません。

次の行find . -type f \( -exec md5sum "$PWD"/{} \; \)は、次の出力を返します。

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

したがって、パスはマシンによって異なります。awk '{print $1}'ファイルのハッシュのみを持つ最初の列を取得するのに役立ちます。後でこれらのハッシュを並べ替える必要がありますが、マシンによって順序が異なる可能性があり、3つ以上のファイルがある場合は異なるハッシュを持つこともあります。


溶液:

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}'
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.