디렉토리 내용의 MD5 합계를 하나의 합계로 얻으려면 어떻게합니까?


171

md5sum 프로그램은 디렉토리에 대한 체크섬을 제공하지 않습니다. 하위 디렉토리의 파일을 포함하여 디렉토리의 전체 내용에 대한 단일 MD5 체크섬을 얻고 싶습니다. 즉, 모든 파일로 구성된 하나의 결합 된 체크섬입니다. 이것을 할 수있는 방법이 있습니까?

답변:


186

올바른 방법은 요구하는 이유에 따라 다릅니다.

옵션 1 : 데이터 만 비교

트리의 파일 내용에 대한 해시가 필요한 경우 다음과 같은 트릭을 수행합니다.

$ find -s somedir -type f -exec md5sum {} \; | md5sum

먼저 모든 파일 내용을 예측 가능한 순서로 개별적으로 요약 한 다음 해당 파일 이름 목록과 MD5 해시를 해시 자체로 전달하여 트리에있는 파일 중 하나의 내용이 변경 될 때만 변경되는 단일 값을 제공합니다.

불행히도 find -smacOS, FreeBSD, NetBSD 및 OpenBSD에서 사용되는 BSD find (1)에서만 작동합니다. GNU 또는 SUS find (1)가있는 시스템에서 비슷한 것을 얻으려면 조금 더 추한 것이 필요합니다.

$ find somedir -type f -exec md5sum {} \; | sort -k 2 | md5sum

find -s에 대한 통화로 교체 되었습니다 sort. 이 -k 2비트는 MD5 해시를 건너 뛰도록 지시하므로 필드 2에서 줄 끝까지의 파일 이름 만 계산하여 정렬합니다 sort.

이 버전의 명령에는 약점이 있습니다. 즉, 줄 바꿈이 포함 된 파일 이름이 있으면 여러 줄로 표시되므로 혼동 될 수 있습니다 sort. find -s트리 탐색 및 정렬이 같은 프로그램 내에서 발생하기 때문에 변형, 그 문제를 가지고 있지 않습니다 find.

두 경우 모두 오탐 (false positive)을 피하기 위해 정렬이 필요합니다. 가장 일반적인 Unix / Linux 파일 시스템은 디렉토리 목록을 안정적이고 예측 가능한 순서로 유지하지 않습니다. ls디렉토리 내용을 자동으로 정렬하는 등의 사용을 인식하지 못할 수 있습니다 . find없이 -s또는 sort호출은 파일의 순서는 입력의 변화로 주어진 경우이 명령이 변경된 해시 값을 제공하게되는, 기본 파일 시스템을 반환 어떤 순서로 파일을 인쇄 할 것입니다.

md5sum명령 md5또는 다른 해시 함수로 명령 을 변경해야 할 수도 있습니다 . 다른 해시 함수를 선택하고 시스템에 대한 두 번째 형식의 명령이 필요한 경우 sort그에 따라 명령 을 조정해야 할 수도 있습니다 . 또 다른 함정은 일부 데이터 합산 프로그램이 파일 이름을 전혀 쓰지 않는다는 것입니다. 예를 들어 구 유닉스 sum프로그램 이 그 대표적인 예 입니다.

이 방법은 md5sumN + 1 번을 호출하는 다소 비효율적입니다. 여기서 N은 트리의 파일 수이지만 파일 및 디렉토리 메타 데이터 해시를 피하는 데 필요한 비용입니다.

옵션 2 : 데이터 메타 데이터 비교

파일 내용뿐만 아니라 트리의 모든 내용이 변경 되었음을 감지해야하는 경우 tar디렉토리 내용을 압축하여 요청하십시오 md5sum.

$ tar -cf - somedir | md5sum

tar파일 권한, 소유권 등도 볼 수 있기 때문에 파일 내용의 변경뿐만 아니라 그에 대한 변경도 감지합니다.

이 방법은 트리를 한 번만 통과하고 해시 프로그램을 한 번만 실행하기 때문에 상당히 빠릅니다.

위의 find기본 방법 과 마찬가지로 tar기본 파일 시스템이 반환하는 순서대로 파일 이름을 처리합니다. 응용 프로그램에서 이러한 일이 발생하지 않도록 할 수도 있습니다. 그럴 가능성이있는 세 가지 다른 사용 패턴을 생각할 수 있습니다. (우리는 지정되지 않은 동작 영역에 들어가기 때문에 그것들을 나열하지 않을 것입니다. 각 파일 시스템은 OS의 버전마다 다를 수 있습니다.)

자신이 오 탐지를 얻는다면 Gilles 'answerfind | cpio옵션을 사용하는 것이 좋습니다 .


7
비교하는 디렉토리로 이동하여 find .대신에 사용하는 것이 가장 좋습니다 find somedir. 이 방법으로 찾을 다른 경로 스펙을 제공 할 때 파일 이름이 동일합니다. 이것은 까다로울 수 있습니다 :-)
Abbafei

파일도 정렬해야합니까?
CMCDragonkai 2016 년

@CMCDragonkai : 무슨 뜻인가요? 첫 번째 경우에, 우리는 파일 이름 목록을 정렬합니다. 두 번째 경우, 첫 번째 문장에서 강조된 것의 일부가 디렉토리의 파일 순서가 변경되었으므로 어떤 것도 정렬하고 싶지 않기 때문에 의도적으로하지 않습니다 .
워렌 영

@WarrenYoung 옵션 2가 왜 항상 더 좋은지는 아닌지 좀 더 자세히 설명 할 수 있습니까? 더 빠르고 간단하며 더 크로스 플랫폼 인 것 같습니다. 어떤 경우에 옵션 1이 아니어야합니까?
로빈 윈 슬로

옵션 1 대안 : find somedir -type f -exec sh -c "openssl dgst -sha1 -binary {} | xxd -p" \; | sort | openssl dgst -sha1모든 파일 이름을 무시하려면 (개행과 함께 작동해야 함)
windm

38

체크섬은 파일을 문자열로 결정적이고 명확하게 표현해야합니다. 결정 론적이란 동일한 위치에 동일한 파일을 배치하면 동일한 결과를 얻을 수 있음을 의미합니다. 명백한 것은 두 개의 서로 다른 파일 세트가 서로 다른 표현을 가지고 있음을 의미합니다.

데이터 및 메타 데이터

파일을 포함하는 아카이브를 만드는 것이 좋습니다. 이것은 명백한 표현입니다 (아카이브를 추출하여 파일을 복구 할 수 있기 때문에). 날짜 및 소유권과 같은 파일 메타 데이터를 포함 할 수 있습니다. 그러나 이것은 아직 옳지 않습니다. 아카이브는 파일이 저장된 순서와 압축에 적용 가능한 경우에 따라 다르기 때문에 모호합니다.

해결책은 파일 이름을 아카이브하기 전에 정렬하는 것입니다. 파일 이름에 줄 바꿈이 포함되어 있지 않으면 파일 find | sort을 나열하여 순서대로 아카이브에 추가 할 수 있습니다. 아카이버에게 디렉토리로 돌아 가지 않도록주의하십시오. POSIX pax, GNU tar 및 cpio의 예는 다음과 같습니다 .

find | LC_ALL=C sort | pax -w -d | md5sum
find | LC_ALL=C sort | tar -cf - -T - --no-recursion | md5sum
find | LC_ALL=C sort | cpio -o | md5sum

이름과 내용 만, 최첨단 방식

메타 데이터가 아닌 파일 데이터 만 고려하려는 경우 파일 내용 만 포함하는 아카이브를 만들 수 있지만이를위한 표준 도구는 없습니다. 파일 내용을 포함하는 대신 파일의 해시를 포함시킬 수 있습니다. 파일 이름에 줄 바꿈이없고 일반 파일과 디렉토리 만있는 경우 (심볼릭 링크 나 특수 파일이없는 경우) 매우 쉽지만 몇 가지 사항을주의해야합니다.

{ export LC_ALL=C;
  find -type f -exec wc -c {} \; | sort; echo;
  find -type f -exec md5sum {} + | sort; echo;
  find . -type d | sort; find . -type d | sort | md5sum;
} | md5sum

빈 디렉토리는 보이지 않으므로 체크섬 목록과 함께 디렉토리 목록을 포함합니다. 파일 목록이 정렬되어 있습니다 (Peter.O 덕분에 특정 재현 가능한 로케일로). echo두 부분을 분리합니다 (이것없이 md5sum일반 파일을 전달할 수있는 출력 처럼 보이는 빈 디렉토리를 만들 수 있습니다). 길이 확장 공격 을 피하기 위해 파일 크기 목록도 포함합니다 .

그건 그렇고, MD5는 더 이상 사용되지 않습니다. 사용 가능한 경우 SHA-2 또는 SHA-1 이상을 사용하십시오.

이름의 개행을 지원하는 이름과 데이터

다음은 GNU 도구를 사용하여 파일 이름을 null 바이트로 구분하는 위의 코드 변형입니다. 이렇게하면 파일 이름에 줄 바꾸기가 포함될 수 있습니다. GNU 다이제스트 유틸리티는 출력에서 ​​특수 문자를 인용하므로 모호한 줄 바꿈이 없습니다.

{ export LC_ALL=C;
  du -0ab | sort -z; # file lengths, including directories (with length 0)
  echo | tr '\n' '\000'; # separator
  find -type f -exec sha256sum {} + | sort -z; # file hashes
  echo | tr '\n' '\000'; # separator
  echo "End of hashed data."; # End of input marker
} | sha256sum

보다 강력한 접근법

다음은 파일 계층 구조를 설명하는 해시를 빌드하는 최소한의 테스트를 거친 Python 스크립트입니다. 디렉토리 및 파일 내용을 고려하고 기호 링크 및 기타 파일을 무시하고 파일을 읽을 수 없으면 치명적인 오류를 반환합니다.

#! /usr/bin/env python
import hashlib, hmac, os, stat, sys
## Return the hash of the contents of the specified file, as a hex string
def file_hash(name):
    f = open(name)
    h = hashlib.sha256()
    while True:
        buf = f.read(16384)
        if len(buf) == 0: break
        h.update(buf)
    f.close()
    return h.hexdigest()
## Traverse the specified path and update the hash with a description of its
## name and contents
def traverse(h, path):
    rs = os.lstat(path)
    quoted_name = repr(path)
    if stat.S_ISDIR(rs.st_mode):
        h.update('dir ' + quoted_name + '\n')
        for entry in sorted(os.listdir(path)):
            traverse(h, os.path.join(path, entry))
    elif stat.S_ISREG(rs.st_mode):
        h.update('reg ' + quoted_name + ' ')
        h.update(str(rs.st_size) + ' ')
        h.update(file_hash(path) + '\n')
    else: pass # silently symlinks and other special files
h = hashlib.sha256()
for root in sys.argv[1:]: traverse(h, root)
h.update('end\n')
print h.hexdigest()

알았어요, 고마워요 그러나 메타 데이터를 포함하지 않고 수행 할 수있는 방법이 있습니까? 지금은 실제 내용 만 필요합니다.

LC_ALL=C sort다른 환경에서 확인 하는 것은 어떻습니까 ... (+ 1 btw)
Peter.O

이것을 위해 전체 파이썬 프로그램을 만들었습니까? 감사! 이것은 내가 예상했던 것보다 더 많은 것입니다. :-) 어쨌든, 이러한 방법과 Warren의 새로운 옵션 1을 확인하겠습니다.

좋은 대답입니다. LC_ALL=C여러 시스템 및 OS에서 실행중인 경우 정렬 순서를 설정해야합니다 .
Davor Cubranic

무슨 cpio -o -뜻입니까? cpio는 기본적으로 stdin / out을 사용하지 않습니까? GNU cpio 2.12 제작cpio: Too many arguments
Jan Tojnar

12

md5deep보십시오 . 관심을 가질만한 md5deep의 일부 기능 :

재귀 작업-md5deep은 전체 디렉토리 트리를 재귀 적으로 검사 할 수 있습니다. 즉, 디렉토리의 모든 파일 및 모든 서브 디렉토리의 모든 파일에 대해 MD5를 계산하십시오.

비교 모드-md5deep은 알려진 해시 목록을 받아 입력 파일 세트와 비교할 수 있습니다. 프로그램은 알려진 해시 목록과 일치하는 입력 파일 또는 일치하지 않는 입력 파일을 표시 할 수 있습니다.

...


멋지지만 작동시킬 수는 없습니다 .../foo: Is a directory.
Camilo Martin

3
자체 md5deep에서는 통합 md5sum을 인쇄하지 않으므로 OP의 문제를 해결하지 않고 디렉토리의 각 파일에 대해 md5sum 만 인쇄합니다. 즉, OP가 원했던 것은 아니지만 md5deep의 출력을 md5sum 할 수 있습니다 . 예 : 현재 디렉토리의 경우 : md5deep -r -l -j0 . | md5sum( -r재귀 적 인 곳 은 -l"상대 경로 사용"을 의미하므로 두 디렉토리의 내용을 비교하려고 할 때 파일의 절대 경로가 방해받지 않으며 -j01 스레드를 사용하여 비결 정성 방지 개별 md5sum에 다른 순서로 반환 됨).
Stevie

경로에서 일부 파일 / 디렉토리를 무시하는 방법?
Sandeepan Nath

9

목표가 두 디렉토리 사이의 차이점을 찾는 것이라면 diff 사용을 고려하십시오.

이 시도:

diff -qr dir1 dir2

예, 이것도 유용합니다. 그 명령에서 dir1 dir2를 의미한다고 생각합니다.

1
나는 일반적으로 GUI를 피할 수있을 때 GUI를 사용하지 않지만 디렉토리 diffing의 경우 kdiff3 는 훌륭하고 많은 플랫폼에서 작동합니다.
sinelaw

이 명령으로 다른 파일도보고됩니다.
Sroo Stroobandt

7

모든 파일을 재귀 적으로 해시 한 다음 결과 텍스트를 해시 할 수 있습니다.

> md5deep -r -l . | sort | md5sum
d43417958e47758c6405b5098f151074 *-

md5deep 이 필요합니다.


1
md5deep 패키지는 해시 딥의 임시 더미이기 때문에 우분투 16.04 에서 md5deep사용 hashdeep하는 대신 .
palik

1
해시 딥을 시도했습니다. 해시뿐만 아니라 ## Invoked from: /home/myuser/dev/현재 경로와를 포함한 일부 헤더를 출력 합니다 ## $ hashdeep -s -r -l ~/folder/. 정렬해야하므로 현재 폴더 또는 명령 줄을 변경하면 최종 해시가 달라집니다.
truf

3

파일 이름을 제외한 파일 내용

내용이 다른 디렉토리에 있기 때문에 파일 이름 만 확인한 버전이 필요했습니다.

이 버전 (Warren Young 's answer) 은 많은 도움이되었지만 내 버전의 md5sum파일 이름은 (명령을 실행 한 경로와 관련하여) 파일 이름 을 출력하고 폴더 이름은 다릅니다. 따라서 개별 파일 체크섬이 일치하더라도 최종 체크섬은 '티.

이를 해결하기 위해 필자의 경우 find출력 의 각 줄에서 파일 이름을 제거해야했습니다 (을 사용하여 공백으로 구분 된 첫 번째 단어 만 선택하십시오 cut).

find -s somedir -type f -exec md5sum {} \; | cut -d" " -f1 | md5sum

재현 가능한 목록을 얻으려면 체크섬을 정렬해야 할 수도 있습니다.
eckes

3

해결책 :

$ pip install checksumdir
$ checksumdir -a md5 assets/js
981ac0bc890de594a9f2f40e00f13872
$ checksumdir -a sha1 assets/js
88cd20f115e31a1e1ae381f7291d0c8cd3b92fad

작동 신속 하고 쉽게 다음 솔루션 bash는 스크립트.

문서 참조 : https://pypi.python.org/pypi/checksumdir/1.0.5


pip가없는 경우 yum -y install python-pip (또는 dnf / apt-get)로 설치해야합니다.
DmitrySemenov

3

nix-hash에서 닉스의 패키지 관리자

nix-hash 명령은 각 경로 내용의 암호화 해시를 계산하여 표준 출력에 인쇄합니다. 기본적으로 MD5 해시를 계산하지만 다른 해시 알고리즘도 사용할 수 있습니다. 해시는 16 진수로 인쇄됩니다.

해시는 각 경로의 직렬화 (경로를 기반으로하는 파일 시스템 트리 덤프)를 통해 계산됩니다. 이를 통해 일반 파일뿐만 아니라 디렉토리 및 심볼릭 링크를 해시 할 수 있습니다. 덤프는 nix-store --dump에서 생성 한 NAR 형식입니다. 따라서 nix-hash 경로는 nix-store --dump path | md5sum.


2

나는 이것을 적당한 볼륨으로 내 스 니펫을 사용합니다 .

find . -xdev -type f -print0 | LC_COLLATE=C sort -z | xargs -0 cat | md5sum -

XXXL에 대한 하나 :

find . -xdev -type f -print0 | LC_COLLATE=C sort -z | xargs -0 tail -qc100 | md5sum -


뭐라고합니까 -xdev플래그는 무엇입니까?
czerasz

그것은 당신이 타이핑을 요구합니다 : man find그리고 훌륭한 매뉴얼을 읽으십시오;)
poige

좋은 지적 :-). -xdev Don't descend directories on other filesystems.
czerasz

1
이것은 비어있는 새 파일을 무시합니다 (파일을 터치하는 것처럼).
RonJohn

이것이 완전히 다른 파일 및 디렉토리 구조로 동일한 md5sum을 생성하는 경우가 많이 있습니다. 파일과 디렉토리의 이름을 바꾸면 파일의 정렬 순서가 변경되지 않아도 변경되지 않습니다. 따라서이 접근법을 권장하지 않습니다.
Hans-Peter Störr

2

좋은 트리 체크섬은 Git의 tree-id입니다.

불행히도 사용할 수있는 독립형 도구는 없지만 (최소한 모르겠습니다) Git이 편리한 경우 새 저장소를 설정하고 확인하려는 파일을 색인에 추가하는 것처럼 가장 할 수 있습니다.

이를 통해 컨텐츠, 파일 이름 및 일부 축소 된 파일 모드 (실행 가능) 만 포함하는 (재생 가능한) 트리 해시를 생성 할 수 있습니다.


2

이 훌륭한 답변에 대한 후속 조치로 , 큰 디렉토리의 체크섬 계산 속도를 높이려면 GNU Parallel을 사용해보십시오 .

find -s somedir -type f | parallel -k -n 100 md5 {} | md5

(이는 Mac을 사용하고 md5필요에 따라 교체합니다.)

-k플래그는 그 지시, 중요하다 parallel, 그렇지 않으면 전체 합이 파일이 모두 같은 경우에도 실행 실행 변경할 수 있습니다, 질서를 유지 할 수 있습니다. 100 개의 인수로 -n 100각 인스턴스를 실행한다고하면 md5최상의 런타임을 위해 조정할 수있는 매개 변수입니다. (개인의 경우에는 오류가 발생했지만) -X플래그 도 참조하십시오 parallel.


1

잘 테스트되고 복제본 찾기, 데이터 및 메타 데이터 비교, 추가 및 변경 사항 및 제거 표시를 포함하여 여러 작업을 지원하는 스크립트는 Fingerprint 와 같은 것이 좋습니다.

지문은 현재 디렉토리에 대한 단일 체크섬을 생성하지 않지만 해당 디렉토리에있는 모든 파일에 대한 체크섬을 포함하는 스크립트 파일을 생성합니다.

fingerprint analyze

이것은 index.fingerprint체크섬, 파일 이름 및 파일 크기를 포함하는 현재 디렉토리에서 생성 됩니다. 기본적으로 MD5와를 모두 사용합니다 SHA1.256.

앞으로 Merkle Trees에 대한 지원을 지문에 추가하여 단일 최상위 체크섬을 제공 할 것입니다. 지금은 확인을 위해 해당 파일을 유지해야합니다.


1

새로운 실행 파일이나 복잡한 솔루션을 원하지 않았으므로 여기에 내 취해야합니다.

#!/bin/sh
# md5dir.sh by Camilo Martin, 2014-10-01.
# Give this a parameter and it will calculate an md5 of the directory's contents.
# It only takes into account file contents and paths relative to the directory's root.
# This means that two dirs with different names and locations can hash equally.

if [[ ! -d "$1" ]]; then
    echo "Usage: md5dir.sh <dir_name>"
    exit
fi

d="$(tr '\\' / <<< "$1" | tr -s / | sed 's-/$--')"
c=$((${#d} + 35))
find "$d" -type f -exec md5sum {} \; | cut -c 1-33,$c- | sort | md5sum | cut -c 1-32

0

강력하고 깨끗한 접근

  • 먼저 , 사용 가능한 메모리를 낭비하지 마십시오 ! 전체 파일을 공급하는 대신 파일을 청크로 해시합니다.
  • 다양한 요구 / 목적에 대한 다양한 접근 방식 (아래 모두 또는 적용 대상 선택) :
    • 디렉토리 트리에있는 모든 항목의 항목 이름 만 해시
    • 모든 항목의 파일 내용을 해시하십시오 (메타를 남기고, inode 번호, ctime, atime, mtime, size 등을 남겨두면 아이디어를 얻습니다)
    • 심볼릭 링크의 경우 내용은 참조 이름입니다. 해시 또는 건너 뛰기로 선택
    • 항목의 내용을 해시하는 동안 심볼릭 링크를 따르거나 따르지 않음 (확인 된 이름)
    • 디렉토리 인 경우 내용은 디렉토리 항목입니다. 재귀 적으로 순회하는 동안 결국 해시되지만이 디렉토리의 태그를 지정하기 위해 해당 레벨의 디렉토리 항목 이름을 해시해야합니까? 내용을 해시하기 위해 깊이 탐색하지 않고 변경 사항을 신속하게 식별하기 위해 해시가 필요한 사용 사례에 유용합니다. 예를 들어 파일 이름이 변경되지만 나머지 내용은 동일하게 유지되며 모두 상당히 큰 파일입니다.
    • 큰 파일을 잘 처리하십시오 (다시 RAM을 염두에 두십시오)
    • 매우 깊은 디렉토리 트리 처리 (열린 파일 설명자에 유의)
    • 비표준 파일 이름 처리
    • 소켓, 파이프 / FIFO, 블록 장치, 문자 장치 인 파일로 진행하는 방법은 무엇입니까? 그것들도 해시해야합니까?
    • 통과하는 동안 항목의 액세스 시간을 업데이트하지 마십시오. 특정 사용 사례의 경우 부작용이 있고 반 생산적 (직관적인가?)이기 때문입니다.

이것은 내가 머리 위로 가지고있는 것입니다.이 작업을 실제로 한 시간을 보낸 사람은 다른 문제와 모퉁이를 잡을 것입니다.

여기에 도구가 있습니다 (면책 조항 : 나는 그것에 기여합니다) dtreetrawl , 메모리에 매우 가벼워 대부분의 경우를 다루며 가장자리에서 약간 거칠지 만 상당히 도움이되었습니다.

Usage:
  dtreetrawl [OPTION...] "/trawl/me" [path2,...]

Help Options:
  -h, --help                Show help options

Application Options:
  -t, --terse               Produce a terse output; parsable.
  -d, --delim=:             Character or string delimiter/separator for terse output(default ':')
  -l, --max-level=N         Do not traverse tree beyond N level(s)
  --hash                    Hash the files to produce checksums(default is MD5).
  -c, --checksum=md5        Valid hashing algorithms: md5, sha1, sha256, sha512.
  -s, --hash-symlink        Include symbolic links' referent name while calculating the root checksum
  -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

인간 친화적 출력의 예 :

...
... //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

일반적인 조언은 언제나 환영하지만 최선의 답변은 구체적이고 적절한 코드가 있습니다. 도구를 사용한 경험이 있다면 참조하십시오.
bu5hman

트윗 담아 가기 개발에 참여한 후 그것이 얼마나 잘 작동하는지에 대해 더 이상 말하지 않는 것이 좋았습니다.
6-k

0

각 디렉토리의 모든 파일에 대해 개별적으로 수행

# Calculating
find dir1 | xargs md5sum > dir1.md5
find dir2 | xargs md5sum > dir2.md5
# Comparing (and showing the difference)
paste <(sort -k2 dir1.md5) <(sort -k2 dir2.md5) | awk '$1 != $3'

0

POSIX 아카이브 형식으로의 마이그레이션은 GNU Tar 기반 체크섬에 영향을 미칩니다

이 답변은 Tar 출력을 사용하여 디렉토리 내용을 해시하는 접근법에 대한 보충 업데이트입니다. 왜냐하면 그것은 얼마 전에 Warren YoungGilles 의 탁월한 답변에서 제안 된 것처럼 디렉토리 내용을 해시합니다 .

그 이후로 최소한 openSUSE (릴리스 12.2 이후)는 기본 GNU Tar 형식을 "GNU tar 1.13.x 형식" 에서 (약간) 우수한 "POSIX 1003.1-2001 (pax) 형식"으로 변경했습니다 . 또한 상류 (GNU 타르의 개발자들 사이에서) 그들은 예를 들어의 마지막 단락 참조 같은 마이그레이션을 수행하는 토론 이 페이지GNU 타르 설명서를 :

GNU tar의 기본 형식은 컴파일 타임에 정의됩니다. 을 실행 tar --help하고 출력의 마지막 줄을 검사하여 확인할 수 있습니다 . 일반적으로 GNU tar는 gnu형식으로 아카이브를 작성하도록 구성 되지만 이후 버전은로 전환됩니다 posix.

(이 페이지는 GNU Tar에서 사용할 수있는 다양한 아카이브 형식에 대한 좋은 검토도 제공합니다.)

우리의 경우 디렉토리 내용을 tar하고 결과를 해시하고 특별한 조치를 취하지 않으면 GNU에서 POSIX 형식으로 변경하면 다음과 같은 결과가 발생합니다.

  • 동일한 디렉토리 내용에도 불구하고 결과 체크섬은 달라집니다.

  • 동일한 디렉토리 내용에도 불구하고 기본 pax 헤더가 사용되는 경우 결과 체크섬은 실행마다 다릅니다.

후자는 POSIX (pax) 형식 %d/PaxHeaders.%p/%f이 GNU Tar에서 기본적으로 형식 문자열에 의해 결정되는 확장 된 pax 헤더를 포함한다는 사실에서 비롯됩니다 . 이 문자열 내에서 지정 %p자는 생성 Tar 프로세스의 프로세스 ID로 대체되며 실행마다 다릅니다. 참조 이 섹션GNU 타르 설명서 특히 이 하나의 세부 사항을.

2019 년 3 월 28 일부터 지금 까지이 문제를 해결하는 업스트림 커밋이 허용됩니다.

따라서 주어진 사용 사례에서 GNU Tar을 계속 사용하려면 다음과 같은 대체 옵션을 권장 할 수 있습니다.

  • Tar 옵션 --format=gnu을 사용하여 "old"형식으로 아카이브를 생성하도록 Tar에 명시 적으로 지시 하십시오 . "이전"체크섬을 확인하려면 필수입니다.

  • 최신 POSIX 형식을 사용하되 적절한 pax 헤더를 명시 적으로 지정하십시오 (예 : by) --pax-option="exthdr.name=%d/PaxHeaders/%f". 그러나 이로 인해 "이전"체크섬과의 호환성이 손상됩니다.

다음은 메타 데이터를 포함하여 디렉토리 내용의 체크섬을 계산하기 위해 정기적으로 사용하는 Bash 코드 조각입니다.

( export LC_ALL=C
  find <paths> ! -type s -print0 |
  sort -z |
  tar cp --format=gnu --numeric-owner \
         --atime-preserve \
         --no-recursion --null --files-from - |
  md5sum --binary; )

여기서는 <paths>체크섬으로 덮고 싶은 모든 디렉토리 경로의 공백으로 구분 된 목록으로 대체됩니다. C 로케일, 파일 이름의 널 바이트 분리 및 파일 시스템 독립적 인 파일 순서를 아카이브에 얻기 위해 찾기 및 정렬을 사용하는 목적은 이미 다른 답변에서 충분히 논의되었습니다.

주변 괄호는 LC_ALL설정을 서브 쉘에서 로컬로 유지합니다 .

또한 소켓 파일이 디렉토리 내용의 일부인 경우 발생하는 Tar의 경고를 피하기 위해 ! -type swith 표현식 을 사용합니다 find. GNU Tar은 소켓을 아카이브하지 않습니다. 건너 뛴 소켓에 대한 알림을 받으려면 해당 표현식을 멀리 두십시오.

--numeric-ownerTar와 함께 사용 하여 파일 소유자가 모두 알려지지 않은 시스템에서도 나중에 체크섬을 확인할 수 있습니다.

--atime-preserveTar에 대한 옵션 <paths>은 읽기 전용 마운트 장치에있는 경우 생략하는 것이 좋습니다 . 그렇지 않으면 액세스 시간 소인 Tar가 복원 할 수없는 각 단일 파일에 대해 경고가 표시됩니다. write enabled의 <paths>경우이 옵션을 사용하여 해시 디렉토리의 액세스 타임 스탬프를 유지합니다.

Gilles 제안서--no-recursion 에서 이미 사용 된 Tar 옵션 은 Tar이 재귀 적으로 디렉토리로 내려가는 것을 방지하고 정렬 된 출력 에서 공급되는 모든 파일에 대해 파일 단위로 작동하지 않도록합니다 .find

그리고 마지막으로 내가 사용하는 것은 사실이 아닙니다 . md5sum실제로 사용 sha256sum합니다.


-1

md5가 필요하지 않으면 시도해 볼 수 있습니다

find . -type f | xargs cksum | cksum

1
질문은 구체적으로 md5
RalfFriedl
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.