디렉토리의 디렉토리에 대한 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 와 같아야합니다
alper

1
이 외에도 파일의 해시가 정렬되어 정렬 순서가 다른 시스템에서 다른 경우 다른 해시가 발생합니다.
alper

40

나는 일반적으로 "find | 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

그러나 복사 된 디렉토리를 원본 디렉토리와 비교하는 데 사용하는 경우 Kompare 또는 WinMerge를 사용하거나 각 lis의 해시를 가져 와서 다른 디렉토리의 출력 목록과 비교할 txt 파일로 출력을 보냅니다. . 문제는 찾기 도구가 내용을 출력하는 순서가 디렉토리마다 다를 수 있기 때문에 해시가 같은 순서로 계산되지 않았기 때문에 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 및 인용 부호를 추가하여 각 파일 해시를 한 번에 하나씩 계산하여 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)를 통한 파이핑 이 많은 파일을 엉망으로 만드는 것보다 쉽습니다.
Anton Samsonov

@AntonSamsonov이 스크립트는 정말 오래된 스크립트입니다. 당시 스크립트를 배우고있었습니다. 나는 그것을 여러 번 다시 썼다. 귀하의 의견과 관련하여 정렬 할 때 0으로 끝나는 것은 무엇입니까? 나는 정렬 매뉴얼 페이지를 읽었습니다. 그들은 제로 종료가 줄 바꿈 대신 줄 끝에서 0 바이트를 고수한다고 말합니다. 그것이 무엇을 달성합니까?
thebunnyrules

이 스크립트에 대한 별도의 답변으로이 스크립트에 대한 업데이트를 게시했습니다. superuser.com/questions/458326/…
thebunnyrules

4

소개

몇 년 전에 필자는 현재 디렉토리 구조에서 모든 개별 파일의 해시 서명을 확인하고 텍스트 파일의 목록으로 출력 할 수있는 스크립트를이 스레드에서 직접 작성하고 제시했습니다.

그 이후로 나는이 공식을 여러 번 다듬었다. 새롭고 개선 된 스크립트를 여기에 별도의 답변으로 다시 게시하기로 결정했습니다. sha256 용으로 작성되었지만 여전히 sha1을 사용하려는 모든 사용자는 간단한 검색을 수행하고 gedit에서 sha256을 sha1로 교체 할 수 있습니다. 개인적으로, 나는 몇 년 동안 sha1을 사용하지 않았으며 그것이 구식이되고 구글이 그것을 타협 할 수있는 방법을 보여 주었기 때문에 그것을 추천하지 않을 것 입니다.

내 새 스크립트는 다음과 같습니다.

  1. 해시하려는 디렉토리로 이동하여 입력하면 간단히 스크립트를 사용할 수 있습니다.

    sha256rec

    또는 다음을 수행하여 다른 디렉토리에서이 스크립트를 호출 할 수 있습니다.

    sha256rec "/path/to/target/directory/you/want/hash"
  2. 스크립트는 현재 디렉토리에 쓰기 권한이 있는지 감지합니다. 그렇게하면 결과가 현재 디렉토리에 저장됩니다. 쓰기 권한이 없거나 현재 디렉토리가 읽기 전용 시스템 (예 : cdrom)에있는 경우 결과는 현재 사용자의 홈 디렉토리에 저장됩니다.

  3. 스크립트는 일부 하위 디렉토리가 현재 사용자 권한으로 액세스 할 수 없는지를 감지합니다. 모두 읽을 수있는 경우 권한 상승이 발생하지 않으면 권한 상승이 발생하지 않으면 사용자 권한이 루트로 상승됩니다.

  4. 찾기는 현재 디렉토리 구조의 모든 파일 (모든 서브 디렉토리 포함)을 찾는 데 사용됩니다. 정렬은 결과가 알파벳순으로 출력되도록하는 데 사용됩니다. 결과 목록은 sha256sum을 거쳐 텍스트 파일로 출력됩니다.

  5. 이전 스크립트를 작성한 이후로 임시 파일은 악의적이며 가능한 경우 사용자가 악의적 인 제 3 자에 의해 스누핑 및 조작을 할 수있게하므로 피해야하는 디자인 철학을 채택했습니다. 따라서이 새 스크립트의 모든 데이터는 결과가 텍스트 파일로 출력되는 마지막 순간까지 변수로 조작됩니다.

  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. 나노에서는 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 (및 그래픽) 디퓨즈, kdiff, winmerge와 같은 다양한 도구와 비교할 수 있습니다.

  3. 내 파일은 경로를 기준으로 출력을 정렬하여 사람이 쉽게 읽을 수 있도록합니다. sort 명령이 다른 배포판에서 다르게 작동하는 것을 보았습니다. 예를 들어, 한 배포판에서는 대문자가 아닌 대문자보다 우선 순위가 높았고 다른 문자에서는 그렇지 않았습니다. 이는 출력 파일의 행 순서에 영향을 미치며 파일을 비교하기 어렵게 만들 수 있습니다. 항상 같은 배포판에서 스크립트를 사용하고 있지만 해시 목록이 서로 다른 두 환경에서 생성 된 경우에는 아무런 문제가 없습니다. 해시 파일을 추가로 정렬하여 행이 경로가 아닌 해시별로 정렬되도록하여 쉽게 해결할 수 있습니다.

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

보다 강력한 오두막 라인이 될 것이다 #!/usr/bin/env bash- 후자에 설치 될 수 있기 때문에,뿐만 아니라 다른 디렉토리에 강타를 찾을 수 는 / usr / 빈 보다는 / 빈 , 예를 들어, 한편의 ENV는 의 경향 은 / usr / bin에 항상 내가 알기로는 또한 Bash가 필요하기 때문에 [[ blah-blah ]]보다 일반적인 [ blah-blah ]단일 브래킷 변형 대신 이중 브래킷 조건식을 사용할 수 있습니다 .
Anton Samsonov

포인터 주셔서 감사합니다. 방금 조건을 찾아 보았습니다. 그들은 정말 유용 해 보입니다.
thebunnyrules

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와 같은 일부 OS에 대한 타임 스탬프를 포함하며 sha1sum은 실행마다 다릅니다.
rossross

@ rossross가 말한 것. 또한 두 호스트에 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).
  • final md5sum은 파일 체크섬 목록의 체크섬을 계산하므로 한 줄에 전체 디렉토리의 체크섬을 얻으므로 터미널 창에서 시각적으로 쉽게 비교할 수 있습니다.

"MD5가 손상되었다"고 말하기 전에 위협 모델이 무엇인지 명심하십시오. 다른 호스트 나 디스크에서 복사 한 파일이 손상되지 않았는지 확인하려고합니까? 전송 중에 파일이 손상 될 수 있지만 동일한 MD5를 가질 가능성은 0이므로 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 -P0md5sum

이 버전의 명령을 사용하면 두 파일 을 비교할 수 있습니다 /tmp/sums( 두 번째 파일이 동일한 시스템에있는 경우 파일 이름을 바꾸어야 함).


0

해시 된 모든 정보를 포함하는 하나의 거대한 파일을 가지기보다는 트리의 각 폴더에 파일을 만드는 방법을 찾고있었습니다. 나는 여기의 의견에서 영감을 얻었습니다. 광산은 여기에 게시 된 것보다 조금 더 복잡합니다. 파일 회전을 사용하지만 이것은 새로운 플레이어에게는 가장 복잡하지 않습니다. 이 버전에서는 이전 체크섬을 새 체크섬으로 덮어 씁니다. 실행 빈도와 '깊이'필요성에 따라 2-3 버전을 유지하는 것이 좋습니다.

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

[user @ host bin] $ find / 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}'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.