디렉토리의 md5 체크섬을 어떻게 계산할 수 있습니까?


133

*.py디렉토리 및 모든 하위 디렉토리 에있는 특정 유형의 모든 파일 ( 예 :)에 대한 요약 md5 체크섬을 계산해야합니다 .

가장 좋은 방법은 무엇입니까?

편집 : 제안 된 솔루션은 매우 훌륭하지만 이것이 정확히 필요한 것은 아닙니다. 모든 하위 디렉토리의 내용을 포함하여 디렉토리를 전체적으로 고유하게 식별 하는 단일 요약 체크섬 을 얻는 솔루션을 찾고 있습니다.


더 자세한 설명 은 이것이것을 보십시오 .
luvieere 2009

3
나에게 수퍼 유저 질문처럼 보입니다.
Noldorin

8
체크섬은 어떤 것도 고유하게 식별 하지 않습니다 .
Hosam Aly

1
"동일하게"식별하고 싶지 않을 수도있는 두 개의 디렉토리 트리가있는 이유는 무엇입니까? 파일 생성 / 수정 / 액세스 시간이 중요합니까? 버전 관리가 실제로 필요한 것입니까?
jmucchiello

필자의 경우 실제로 중요한 것은 AFAIK를 의미하는 전체 디렉토리 트리 내용의 유사성입니다. 1) 디렉토리 트리 아래의 파일 내용이 변경되지 않았습니다 .2) 디렉토리 트리에 새 파일이 추가되지 않았습니다. 삭제되었습니다
victorz

답변:


152
find /path/to/dir/ -type f -name "*.py" -exec md5sum {} + | awk '{print $1}' | sort | md5sum

find 명령은 .py로 끝나는 모든 파일을 나열합니다. md5sum은 각 .py 파일에 대해 계산됩니다. awk는 md5sum을 선택하는 데 사용됩니다 (파일 이름은 무시할 수 있음). md5sum이 정렬됩니다. 이 정렬 된 목록의 md5sum이 반환됩니다.

테스트 디렉토리를 복사하여 이것을 테스트했습니다.

rsync -a ~/pybin/ ~/pybin2/

~ / pybin2에서 일부 파일의 이름을 변경했습니다.

find...md5sum명령은 두 디렉토리 모두에 대해 동일한 출력을 리턴합니다.

2bcf49a4d19ef9abd284311108d626f1  -

24
파일 이름이 바뀌면 동일한 체크섬이 생성됩니다. 따라서 서명의 파일 레이아웃 부분을 고려할 경우 "디렉토리 전체를 고유하게 식별하는 체크섬"에 맞지 않습니다.
Valentin Milea

1
각 파일 체크섬 앞에 파일 이름 (또는 / path / to / dir /에서 파일의 상대 경로)을 추가하도록 명령 행을 약간 변경하여 최종 체크섬에서 고려할 수 있습니다.
Michael Zilbermann

4
@ zim2001 : 예, 변경 될 수 있지만 문제를 이해했을 때 (특히 OP의 의견으로 인해) OP는 파일의 파일 이름과 상관없이 파일 의 내용 이 동일하거나 상대 경로조차도.
unutbu

@unutbu : 알아요; Valentin Milea의 이전 메모에 반응했습니다.
마이클 질버 만

@ValentinMilea awk ...는 서명의 레이아웃 부분을 고려 하면 부분을 제거합니다 .
segfault

166

즉시 tar 아카이브 파일을 작성하고 다음으로 파이프하십시오 md5sum.

tar c dir | md5sum

그러면 파일 및 하위 디렉토리 설정에 고유 한 단일 md5sum이 생성됩니다. 디스크에 파일이 작성되지 않습니다.


25
하나의 체크섬으로 @CharlesB를 사용하면 어떤 파일이 다른지 알 수 없습니다. 문제는 디렉토리의 단일 체크섬에 관한 것입니다.
Hawken

17
ls -alR dir | md5sum. 압축하지 않고 읽기만하는 것이 더 좋습니다. 내용은 파일의 모드 시간과 크기를 포함하기 때문에 독특합니다.;)
Sid

14
@ Daps0l-내 명령에는 압축이 없습니다. zgzip 또는 jbzip2 에 추가해야합니다 . 나는 둘 다하지 않았다.
ire_and_curses

7
이 작업을 수행하면 파일 내용뿐만 아니라 파일 및 기타 항목의 타임 스탬프가 체크섬 계산에 통합됩니다.
Michael Zilbermann

10
귀엽지 만 실제로 작동하지 않습니다. tar동일한 파일 세트를 두 번 또는 두 대의 다른 컴퓨터에서 사용한다고해서 동일한 결과를 얻을 것이라는 보장은 없습니다 .
fletom

46

ire_and_curses의 사용 제안 tar c <dir>에는 몇 가지 문제가 있습니다.

  • tar는 파일 시스템에 저장된 순서대로 디렉토리 항목을 처리하며이 순서를 변경할 방법이 없습니다. 서로 다른 위치에 "동일한"디렉토리가 있고이 문제를 해결할 방법이없는 경우 (타르가 입력 파일을 특정 순서로 "정렬"할 수없는 경우) 이렇게하면 완전히 다른 결과를 얻을 수 있습니다.
  • 나는 일반적으로 groupid와 ownerid 번호가 같은지에 관심이 있으며, 그룹 / 소유자의 문자열 표현이 반드시 같은지는 아닙니다. 이것은 예를 들어 rsync -a --delete수행 하는 것과 일치합니다. 사실상 모든 것을 (xattrs 및 acls 빼기) 동기화하지만 문자열 표현이 아닌 ID를 기반으로 소유자와 그룹을 동기화합니다. 따라서 반드시 동일한 사용자 / 그룹이없는 다른 시스템에 동기화 한 경우 --numeric-ownertar에 플래그를 추가해야합니다
  • tar는 당신이 확인하고있는 디렉토리의 파일 이름을 포함 할 것입니다.

첫 번째 문제에 대한 해결책이없는 한 (또는 확실하지 않은 경우)이 방법을 사용하지 않습니다.

그만큼 find그들 만 체크섬 마음 빈 디렉토리에 두어야 당신이 경우에 문제가된다 파일이 아닌 디렉토리를 포함하기 때문에 위의 제안을 기반으로 솔루션은 좋지 않습니다.

마지막으로, 시스템에서 데이터 정렬이 다를 수 있으므로 가장 많이 제안 된 솔루션이 일관되게 정렬되지 않습니다.

이것이 내가 생각해 낸 해결책입니다.

dir=<mydir>; (find "$dir" -type f -exec md5sum {} +; find "$dir" -type d) | LC_ALL=C sort | md5sum

이 솔루션에 대한 참고 사항 :

  • 그만큼 LC_ALL=C시스템 전체에서 안정적인 정렬 순서를 보장 입니다
  • 이것은 "named \ nwithanewline"디렉토리와 "named"및 "withanewline"디렉토리 두 개를 구분하지는 않지만 그 가능성은 거의 없습니다. 하나는 일반적으로 이것을 -print0플래그로 수정 find하지만 여기에 다른 일이 있기 때문에 명령을보다 복잡하게 만드는 솔루션 만 볼 수 있습니다.

추신 : 내 시스템 중 하나가 find지원 -exec하지 않거나 -print0플래그 를 지정하지 않는 제한된 busybox 를 사용하며 디렉토리를 나타 내기 위해 '/'를 추가하지만 findutils find는 보이지 않는 것처럼 보입니다.

dir=<mydir>; (find "$dir" -type f | while read f; do md5sum "$f"; done; find "$dir" -type d | sed 's#/$##') | LC_ALL=C sort | md5sum

운 좋게도 이름에 줄 바꿈이있는 파일 / 디렉토리가 없으므로 해당 시스템에서 문제가되지 않습니다.


1
+1 : 매우 흥미 롭습니다! 다른 파일 시스템 유형이나 동일한 파일 시스템 내에서 순서가 다를 수 있다고 말하고 있습니까?
ire_and_curses

2
양자 모두. 각 디렉토리 내의 디렉토리 항목 순서에 따라 다릅니다. 파일 시스템에있는 AFAIK 디렉토리 항목은 "디렉토리에 파일을 생성하는"순서대로 생성됩니다. 간단한 예 : $ mkdir a; 터치 / 파일 -1; 터치 a / file-2 $ mkdir b; 터치 b / 파일 -2; 터치 B / 파일 1 $ (CD a 및 타르 -c | md5sum이.) fb29e7af140aeea5a2647974f7cdec77 - $ (CD를 B,. 타르 -c | md5sum이) a3a39358158a87059b9f111ccffa1023 -
Dieter_be

15

빈 디렉토리가 아닌 파일 만 신경 쓰면 잘 작동합니다.

find /path -type f | sort -u | xargs cat | md5sum


9

나에게 가장 적합한 솔루션 :

find "$path" -type f -print0 | sort -z | xargs -r0 md5sum | md5sum

그것이 나를 위해 가장 효과가 있었던 이유 :

  1. 공백이 포함 된 파일 이름을 처리합니다.
  2. 파일 시스템 메타 데이터를 무시합니다
  3. 파일 이름이 변경되었는지 감지

다른 답변 관련 문제 :

파일 시스템 메타 데이터는 다음에 대해 무시되지 않습니다.

tar c - "$path" | md5sum

공백이 포함 된 파일 이름을 처리하지 않거나 파일 이름이 바뀌 었는지 감지하지 않습니다.

find /path -type f | sort -u | xargs cat | md5sum

4

전체 디렉토리에 걸쳐 하나의 md5sum을 원한다면 다음과 같이하십시오.

cat *.py | md5sum 

1
하위 디렉토리의 경우 cat **.py| md5sum
Ramon

3

내용과 파일 이름을 포함한 모든 파일을 체크섬

grep -ar -e . /your/dir | md5sum | cut -c-32

위와 동일하지만 * .py 파일 만 포함

grep -ar -e . --include="*.py" /your/dir | md5sum | cut -c-32

원하는 경우 심볼릭 링크를 따를 수도 있습니다

grep -aR -e . /your/dir | md5sum | cut -c-32

grep과 함께 사용할 수있는 다른 옵션

-s, --no-messages         suppress error messages
-D, --devices=ACTION      how to handle devices, FIFOs and sockets;
-Z, --null                print 0 byte after FILE name
-U, --binary              do not strip CR characters at EOL (MSDOS/Windows)


2

기술적으로 당신은 실행해야합니다 ls -lR *.py | md5sum. 누군가 파일을 수정하고 원래 날짜로 다시 터치하고 파일 크기를 변경하지 않는 것에 대해 걱정하지 않는 한 출력 결과 ls는 파일이 변경되었는지 알려줍니다. 내 unix-foo는 약하므로 작성 시간과 인쇄 시간을 수정하기 위해 명령 줄 매개 변수가 더 필요할 수 있습니다. ls또한 파일에 대한 권한이 변경되었는지 알려줍니다 (그리고 신경 쓰지 않으면 끌 수있는 스위치가 있다고 확신합니다).


3
이것은 일부 사용 사례에 적합 할 수 있지만 일반적으로 체크섬이 날짜 만 아니라 내용 만 반영하기를 원할 것입니다. 예를 들어, touch파일 의 내용이 아닌 날짜를 변경하는 파일 인 경우 체크섬이 변경되지 않을 것으로 예상합니다.
Todd Owen


1

나는 같은 문제가 있었기 때문에 디렉토리에있는 파일의 md5sum을 나열하는이 스크립트를 생각해 냈고 하위 디렉토리를 찾으면 다시 실행됩니다.이를 위해서는 스크립트가 현재를 통해 실행될 수 있어야합니다 인수가 $ 1로 전달되는 경우 디렉토리 또는 서브 디렉토리에서

#!/bin/bash

if [ -z "$1" ] ; then

# loop in current dir
ls | while read line; do
  ecriv=`pwd`"/"$line
if [ -f $ecriv ] ; then
    md5sum "$ecriv"
elif [ -d $ecriv ] ; then
    sh myScript "$line" # call this script again
fi

done


else # if a directory is specified in argument $1

ls "$1" | while read line; do
  ecriv=`pwd`"/$1/"$line

if [ -f $ecriv ] ; then
    md5sum "$ecriv"

elif [ -d $ecriv ] ; then
    sh myScript "$line"
fi

done


fi

파일 이름에 공백이나 따옴표가 포함되어 있으면이 스크립트가 실패합니다. 나는 bash 스크립팅으로 성가신 것을 알지만, 내가하는 일은 IFS를 변경하는 것입니다.
localhost

1

파일 시스템 속성과 일부 tar 버전의 비트 수준 차이와의 독립성을 원한다면 cpio를 사용할 수 있습니다.

cpio -i -e theDirname | md5sum

0

두 가지 솔루션이 더 있습니다.

창조하다:

du -csxb /path | md5sum > file

ls -alR -I dev -I run -I sys -I tmp -I proc /path | md5sum > /tmp/file

검사:

du -csxb /path | md5sum -c file

ls -alR -I dev -I run -I sys -I tmp -I proc /path | md5sum -c /tmp/file

0

md5sum나를 위해 잘 작동했지만 sort파일 이름을 정렬하고 정렬하는 데 문제가있었습니다 . 대신 md5sum결과 별로 정렬했습니다 . 비슷한 결과를 내기 위해 일부 파일을 제외해야했습니다.

find . -type f -print0 \ | xargs -r0 md5sum \ | grep -v ".env" \ | grep -v "vendor/autoload.php" \ | grep -v "vendor/composer/" \ | sort -d \ | md5sum

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