Làm cách nào để tôi lấy tổng MD5 của nội dung thư mục dưới dạng một tổng?


171

Chương trình md5sum không cung cấp tổng kiểm tra cho các thư mục. Tôi muốn nhận một tổng kiểm tra MD5 cho toàn bộ nội dung của một thư mục, bao gồm các tệp trong các thư mục con. Đó là, một tổng kiểm tra được tạo từ tất cả các tệp. Có cách nào để làm việc này không?

Câu trả lời:


186

Cách đúng phụ thuộc vào chính xác lý do tại sao bạn hỏi:

Tùy chọn 1: Chỉ so sánh dữ liệu

Nếu bạn chỉ cần một hàm băm của nội dung tệp của cây, điều này sẽ thực hiện thủ thuật:

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

Điều này trước tiên tóm tắt tất cả các nội dung tệp riêng lẻ, theo thứ tự dự đoán, sau đó chuyển danh sách tên tệp và băm MD5 đó để tự băm, đưa ra một giá trị duy nhất chỉ thay đổi khi nội dung của một trong các tệp trong cây thay đổi.

Thật không may, find -schỉ hoạt động với BSD find (1), được sử dụng trong macOS, FreeBSD, NetBSD và OpenBSD. Để có được một cái gì đó có thể so sánh trên một hệ thống với GNU hoặc SUS find (1), bạn cần một cái gì đó xấu hơn một chút:

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

Chúng tôi đã thay thế find -sbằng một cuộc gọi đến sort. Các -k 2chút cho nó để bỏ qua băm MD5, vì vậy nó chỉ sắp xếp các tên tập tin, mà là trong lĩnh vực 2 đến end-of-line, bởi sort's phán xét.

Có một điểm yếu với phiên bản lệnh này, đó là có thể bị nhầm lẫn nếu bạn có bất kỳ tên tệp nào có dòng mới trong đó, bởi vì nó sẽ giống như nhiều dòng trong sortcuộc gọi. Các find -sbiến thể không có vấn đề đó, vì duyệt cây và phân loại xảy ra trong cùng một chương trình, find.

Trong cả hai trường hợp, việc sắp xếp là cần thiết để tránh các lỗi tích cực: các hệ thống tệp Unix / Linux phổ biến nhất không duy trì danh sách thư mục theo thứ tự ổn định, có thể dự đoán được. Bạn có thể không nhận ra điều này từ việc sử dụng lsvà như vậy, mà âm thầm sắp xếp nội dung thư mục cho bạn. findkhông có -shoặc một sortcuộc gọi sẽ in ra các tệp theo bất kỳ thứ tự nào mà hệ thống tệp bên dưới trả về chúng, điều này sẽ khiến lệnh này đưa ra giá trị băm thay đổi nếu thứ tự các tệp được cung cấp cho nó khi thay đổi đầu vào.

Bạn có thể cần phải thay đổi các md5sumlệnh thành md5hoặc một số hàm băm khác. Nếu bạn chọn một hàm băm khác và cần dạng lệnh thứ hai cho hệ thống của mình, bạn có thể cần điều chỉnh sortlệnh cho phù hợp. Một cái bẫy khác là một số chương trình tổng hợp dữ liệu hoàn toàn không viết tên tệp, một ví dụ điển hình là sumchương trình Unix cũ .

Phương pháp này có phần không hiệu quả, gọi md5sumN + 1 lần, trong đó N là số lượng tệp trong cây, nhưng đó là một chi phí cần thiết để tránh băm tập tin và siêu dữ liệu thư mục.

Tùy chọn 2: So sánh dữ liệu siêu dữ liệu

Nếu bạn cần có khả năng phát hiện bất cứ thứ gì trong cây đã thay đổi, không chỉ là nội dung tệp, hãy yêu cầu tarđóng gói nội dung thư mục cho bạn, sau đó gửi nó tới md5sum:

$ tar -cf - somedir | md5sum

Bởi vì tarcũng thấy quyền truy cập tệp, quyền sở hữu, v.v., điều này cũng sẽ phát hiện các thay đổi đối với những điều đó, không chỉ thay đổi nội dung tệp.

Phương pháp này nhanh hơn đáng kể, vì nó chỉ thực hiện một lần vượt qua cây và chỉ chạy chương trình băm một lần.

Như với findphương thức dựa trên, tarsẽ xử lý tên tệp theo thứ tự hệ thống tệp bên dưới trả về chúng. Cũng có thể là trong ứng dụng của bạn, bạn có thể chắc chắn rằng mình sẽ không khiến điều này xảy ra. Tôi có thể nghĩ về ít nhất ba mô hình sử dụng khác nhau trong đó có khả năng là trường hợp. (Tôi sẽ không liệt kê chúng, bởi vì chúng tôi đang xâm nhập vào lãnh thổ hành vi không xác định. Mỗi hệ thống tệp có thể khác nhau ở đây, thậm chí từ một phiên bản HĐH này sang phiên bản tiếp theo.)

Nếu bạn thấy mình nhận được thông báo sai, tôi khuyên bạn nên sử dụng find | cpiotùy chọn trong câu trả lời của Gilles .


7
Tôi nghĩ rằng tốt nhất là điều hướng đến thư mục được so sánh và sử dụng find .thay vì find somedir. Bằng cách này, tên tệp giống nhau khi cung cấp các thông số đường dẫn khác nhau để tìm; điều này có thể khó khăn :-)
Abbafei

Chúng ta có nên sắp xếp các tập tin quá không?
CMCDragonkai

@CMCDragonkai: Ý bạn là gì? Trong trường hợp đầu tiên, chúng tôi làm sắp xếp danh sách các tên tập tin. Trong trường hợp thứ hai, chúng tôi cố tình không vì một phần của bất cứ điều gì được nhấn mạnh trong câu đầu tiên là thứ tự các tệp trong một thư mục đã thay đổi, vì vậy bạn sẽ không muốn sắp xếp bất cứ điều gì.
Warren Young

@WarrenYoung Bạn có thể giải thích kỹ hơn một chút tại sao tùy chọn 2 không phải lúc nào cũng tốt hơn không? Nó dường như nhanh hơn, đơn giản hơn và đa nền tảng hơn. Trong trường hợp nào không nên là tùy chọn 1?
Robin Winslow

Lựa chọn thay thế 1: find somedir -type f -exec sh -c "openssl dgst -sha1 -binary {} | xxd -p" \; | sort | openssl dgst -sha1bỏ qua tất cả tên tệp (nên hoạt động với dòng mới)
Windm

38

Tổng kiểm tra cần phải là một đại diện xác định và rõ ràng của các tệp dưới dạng một chuỗi. Xác định có nghĩa là nếu bạn đặt cùng một tệp tại cùng một vị trí, bạn sẽ nhận được kết quả tương tự. Không rõ ràng có nghĩa là hai bộ tệp khác nhau có các biểu diễn khác nhau.

Dữ liệu và siêu dữ liệu

Tạo một kho lưu trữ chứa các tập tin là một khởi đầu tốt. Đây là một đại diện rõ ràng (rõ ràng, vì bạn có thể khôi phục các tệp bằng cách trích xuất kho lưu trữ). Nó có thể bao gồm siêu dữ liệu tệp như ngày và quyền sở hữu. Tuy nhiên, điều này vẫn chưa hoàn toàn đúng: một kho lưu trữ không rõ ràng, bởi vì đại diện của nó phụ thuộc vào thứ tự các tệp được lưu trữ và nếu có thể áp dụng cho việc nén.

Một giải pháp là sắp xếp tên tệp trước khi lưu trữ chúng. Nếu tên tệp của bạn không chứa dòng mới, bạn có thể chạy find | sortđể liệt kê chúng và thêm chúng vào kho lưu trữ theo thứ tự này. Hãy cẩn thận để nói với người lưu trữ không tái diễn vào các thư mục. Dưới đây là các ví dụ với POSIX pax, GNU tar và 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

Chỉ tên và nội dung, cách công nghệ thấp

Nếu bạn chỉ muốn đưa dữ liệu tệp vào tài khoản và không phải siêu dữ liệu, bạn có thể tạo một kho lưu trữ chỉ bao gồm nội dung tệp, nhưng không có công cụ tiêu chuẩn nào cho việc đó. Thay vì bao gồm nội dung tệp, bạn có thể bao gồm hàm băm của tệp. Nếu tên tệp không chứa dòng mới và chỉ có các tệp và thư mục thông thường (không có liên kết tượng trưng hoặc tệp đặc biệt), thì điều này khá dễ dàng, nhưng bạn cần phải quan tâm đến một số điều:

{ 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

Chúng tôi bao gồm một danh sách thư mục bên cạnh danh sách tổng kiểm tra, vì nếu không các thư mục trống sẽ vô hình. Danh sách tập tin được sắp xếp (trong một ngôn ngữ cụ thể, có thể tái tạo - cảm ơn Peter.O đã nhắc nhở tôi về điều đó). echotách hai phần (không có phần này, bạn có thể tạo một số thư mục trống có tên giống như md5sumđầu ra cũng có thể chuyển cho các tệp thông thường). Chúng tôi cũng bao gồm một danh sách các kích thước tệp, để tránh các cuộc tấn công kéo dài .

Nhân tiện, MD5 không được dùng nữa. Nếu có sẵn, hãy cân nhắc sử dụng SHA-2 hoặc ít nhất là SHA-1.

Tên và dữ liệu, hỗ trợ các dòng mới trong tên

Đây là một biến thể của mã ở trên dựa trên các công cụ GNU để phân tách tên tệp bằng byte rỗng. Điều này cho phép tên tệp chứa dòng mới. Các tiện ích tiêu hóa GNU trích dẫn các ký tự đặc biệt trong đầu ra của chúng, vì vậy sẽ không có các dòng mới mơ hồ.

{ 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

Một cách tiếp cận mạnh mẽ hơn

Đây là tập lệnh Python được kiểm tra tối thiểu, xây dựng hàm băm mô tả phân cấp các tệp. Nó đưa các thư mục và nội dung tệp vào tài khoản và bỏ qua các liên kết tượng trưng và các tệp khác và trả về một lỗi nghiêm trọng nếu bất kỳ tệp nào không thể đọc được.

#! /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()

OK, điều này hoạt động, cảm ơn. Nhưng có cách nào để làm điều đó mà không bao gồm bất kỳ siêu dữ liệu nào không? Ngay bây giờ tôi cần nó cho các nội dung thực tế.

Còn về LC_ALL=C sortviệc kiểm tra từ các môi trường khác nhau ... (+ 1 btw)
Peter.O

Bạn đã thực hiện toàn bộ chương trình Python cho việc này? Cảm ơn! Điều này thực sự nhiều hơn những gì tôi đã mong đợi. :-) Dù sao, tôi sẽ kiểm tra các phương pháp này cũng như tùy chọn mới 1 của Warren.

Câu trả lời tốt. Đặt thứ tự sắp xếp LC_ALL=Clà rất cần thiết nếu chạy trên nhiều máy và HĐH.
Davor Cubranic

cpio -o -nghĩa là gì? Không cpio sử dụng stdin / out theo mặc định? GNU cpio 2.12 sản xuấtcpio: Too many arguments
Jan Tojnar

12

Có một cái nhìn tại md5deep . Một số tính năng của md5deep có thể khiến bạn quan tâm:

Hoạt động đệ quy - md5deep có thể kiểm tra đệ quy toàn bộ cây thư mục. Đó là, tính toán MD5 cho mọi tệp trong một thư mục và cho mọi tệp trong mọi thư mục con.

Chế độ so sánh - md5deep có thể chấp nhận danh sách các giá trị băm đã biết và so sánh chúng với một tập hợp các tệp đầu vào. Chương trình có thể hiển thị các tệp đầu vào khớp với danh sách các giá trị băm đã biết hoặc các tệp không khớp.

...


Đẹp, nhưng không thể làm cho nó hoạt động, nó nói .../foo: Is a directory, những gì cho?
Camilo Martin

3
Trên md5deep của chính nó không giải quyết được vấn đề của OP vì nó không in md5sum hợp nhất, nó chỉ in md5sum cho mỗi tệp trong thư mục. Điều đó nói rằng, bạn có thể md5sum đầu ra của md5deep - không hoàn toàn như những gì OP muốn, nhưng đã gần! ví dụ: đối với thư mục hiện tại: md5deep -r -l -j0 . | md5sum(trong đó -rlà đệ quy, -lcó nghĩa là "sử dụng các đường dẫn tương đối" để đường dẫn tuyệt đối của các tệp không can thiệp khi cố gắng so sánh nội dung của hai thư mục và -j0có nghĩa là sử dụng 1 luồng để ngăn chặn sự không xác định do để md5sums cá nhân được trả lại theo thứ tự khác nhau).
Stevie

Làm thế nào để bỏ qua một số tập tin / thư mục trong đường dẫn?
Sandeepan Nath

9

Nếu mục tiêu của bạn chỉ là tìm sự khác biệt giữa hai thư mục, hãy xem xét sử dụng diff.

Thử đi:

diff -qr dir1 dir2

Vâng, điều này cũng hữu ích. Tôi nghĩ bạn có nghĩa là dir1 dir2 trong lệnh đó.

1
Tôi thường không sử dụng GUI khi tôi có thể tránh chúng, nhưng đối với thư mục diff kdiff3 thì tuyệt vời và cũng hoạt động trên nhiều nền tảng.
sinelaw

Các tập tin khác nhau cũng được báo cáo với lệnh này.
Serge Stroobandt

7

Bạn có thể băm mọi tệp đệ quy và sau đó băm văn bản kết quả:

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

md5deep là bắt buộc.


1
thay vì md5deepsử dụng hashdeeptrên Ubuntu 16.04 vì gói md5deep chỉ là một hình nộm chuyển tiếp cho hashdeep.
palik

1
Tôi đã thử hashdeep. Nó xuất ra không chỉ băm mà còn một số tiêu đề bao gồm cả ## Invoked from: /home/myuser/dev/đường dẫn hiện tại của bạn và ## $ hashdeep -s -r -l ~/folder/. Điều này phải sắp xếp, vì vậy hàm băm cuối cùng sẽ khác nếu bạn thay đổi thư mục hoặc dòng lệnh hiện tại.
truf

3

Chỉ nội dung tệp , không bao gồm tên tệp

Tôi cần một phiên bản chỉ kiểm tra tên tệp vì nội dung nằm trong các thư mục khác nhau.

Phiên bản này (câu trả lời của Warren Young) đã giúp ích rất nhiều, nhưng phiên bản md5sumxuất ra tên tệp của tôi (liên quan đến đường dẫn tôi chạy lệnh từ đó) và tên thư mục khác nhau, do đó, mặc dù tổng kiểm tra tệp riêng lẻ đã khớp, nhưng tổng kiểm tra cuối cùng đã không 't.

Để khắc phục điều đó, trong trường hợp của tôi, tôi chỉ cần loại bỏ tên tệp từ mỗi dòng của findđầu ra (chỉ chọn từ đầu tiên được phân tách bằng khoảng trắng bằng cách sử dụng cut):

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

Bạn có thể cần phải sắp xếp tổng kiểm tra để có được một danh sách có thể lặp lại.
eckes 22/03/2016

3

giải pháp :

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

làm việc nhanh chóngdễ dàng hơn giải pháp sau đó bash scripting.

xem tài liệu: https://pypi.python.org/pypi/checksumdir/1.0.5


nếu bạn không có pip, bạn có thể cần cài đặt nó với yum -y cài đặt python-pip (hoặc dnf / apt-get)
DmitrySemenov

3

nix-hashtừ người quản lý gói Nix

Lệnh nix-hash tính toán hàm băm mật mã của nội dung của từng đường dẫn và in nó trên đầu ra tiêu chuẩn. Theo mặc định, nó tính toán hàm băm MD5, nhưng các thuật toán băm khác cũng có sẵn. Băm được in theo hệ thập lục phân.

Hàm băm được tính toán qua một chuỗi tuần tự của mỗi đường dẫn: kết xuất của cây hệ thống tập tin bắt nguồn từ đường dẫn. Điều này cho phép các thư mục và symlink được băm cũng như các tệp thông thường. Các bãi chứa ở định dạng NAR được sản xuất bởi nix-store --dump. Do đó, đường dẫn nix-hash mang lại hàm băm mật mã giống như đường dẫn nix-store --dump | md5sum.


2

Tôi sử dụng đoạn mã này cho khối lượng vừa phải :

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

và cái này cho XXXL :

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


Không những gì -xdevcờ làm gì?
czerasz

Nó kêu gọi bạn gõ vào: man findvà đọc hướng dẫn sử dụng tốt đó;)
poige

Điểm tốt :-). -xdev Don't descend directories on other filesystems.
czerasz

1
Lưu ý rằng điều này bỏ qua các tệp mới, trống (như nếu bạn chạm vào một tệp).
RonJohn

Có nhiều trường hợp điều này sẽ mang lại cùng md5sum với cấu trúc tệp và thư mục hoàn toàn khác nhau. Đổi tên tệp và thư mục sẽ không thay đổi điều đó nếu nó không thay đổi thứ tự sắp xếp của các tệp. Vì vậy, tôi sẽ không đề nghị phương pháp này.
Hans-Peter Störr

2

Tổng kiểm tra cây tốt là id cây của Git.

Thật không may, không có công cụ độc lập nào có thể làm được điều đó (ít nhất là tôi không biết), nhưng nếu bạn có Git tiện dụng, bạn có thể giả vờ thiết lập một kho lưu trữ mới và thêm các tệp bạn muốn kiểm tra vào chỉ mục.

Điều này cho phép bạn tạo ra hàm băm cây (có thể tái tạo) - chỉ bao gồm nội dung, tên tệp và một số chế độ tệp giảm (thực thi).


2

Để theo dõi câu trả lời tuyệt vời này , nếu bạn thấy mình muốn tăng tốc tính toán tổng kiểm tra cho một thư mục lớn, hãy thử GNU Parallel :

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

(Đây là sử dụng máy Mac md5, thay thế khi cần.)

Các -klá cờ là quan trọng, mà chỉ thị parallelđể duy trì trật tự, nếu không số tiền tổng thể có thể thay đổi chạy tới chạy ngay cả khi các file đều như nhau. -n 100nói để chạy từng phiên bản md5với 100 đối số, đây là tham số bạn có thể điều chỉnh để có thời gian chạy tốt nhất. Xem thêm -Xcờ của parallel(mặc dù trong trường hợp cá nhân của tôi đã gây ra lỗi.)


1

Một tập lệnh được kiểm tra tốt và hỗ trợ một số thao tác bao gồm tìm các bản sao, thực hiện so sánh trên cả dữ liệu và siêu dữ liệu, hiển thị các bổ sung cũng như thay đổi và xóa, bạn có thể thích Dấu vân tay .

Dấu vân tay ngay bây giờ không tạo ra một tổng kiểm tra cho một thư mục, nhưng một tệp bản ghi bao gồm tổng kiểm tra cho tất cả các tệp trong thư mục đó.

fingerprint analyze

Điều này sẽ tạo ra index.fingerprinttrong thư mục hiện tại bao gồm tổng kiểm tra, tên tệp và kích thước tệp. Theo mặc định, nó sử dụng cả hai MD5SHA1.256.

Trong tương lai, tôi hy vọng sẽ thêm hỗ trợ cho Merkle Tree vào Dấu vân tay sẽ cung cấp cho bạn một tổng kiểm tra cấp cao nhất. Ngay bây giờ, bạn cần giữ lại tệp đó để thực hiện xác minh.


1

Tôi không muốn các giải pháp thực thi mới cũng như các giải pháp khó hiểu vì vậy đây là của tôi:

#!/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

Một cách tiếp cận mạnh mẽ và sạch sẽ

  • Trước tiên, đừng hog bộ nhớ có sẵn ! Băm một tệp trong khối chứ không phải cho ăn toàn bộ tệp.
  • Các cách tiếp cận khác nhau cho các nhu cầu / mục đích khác nhau (tất cả các cách dưới đây hoặc chọn những gì từng áp dụng):
    • Chỉ băm tên mục nhập của tất cả các mục trong cây thư mục
    • Băm nội dung tệp của tất cả các mục (để lại meta như, số inode, ctime, atime, mtime, kích thước, v.v., bạn có ý tưởng)
    • Đối với một liên kết tượng trưng, ​​nội dung của nó là tên người giới thiệu. Băm nó hoặc chọn bỏ qua
    • Theo dõi hoặc không theo dõi (tên đã giải quyết) liên kết tượng trưng trong khi băm nội dung của mục nhập
    • Nếu đó là một thư mục, nội dung của nó chỉ là các mục trong thư mục. Trong khi duyệt qua đệ quy cuối cùng chúng sẽ được băm nhưng tên mục nhập thư mục của cấp đó có được băm để gắn thẻ thư mục này không? Hữu ích trong các trường hợp sử dụng khi yêu cầu băm để xác định thay đổi nhanh chóng mà không cần phải duyệt sâu để băm nội dung. Một ví dụ sẽ là thay đổi tên của tệp nhưng phần còn lại của nội dung vẫn giữ nguyên và chúng đều là các tệp khá lớn
    • Xử lý tốt các tệp lớn (một lần nữa, lưu ý đến RAM)
    • Xử lý cây thư mục rất sâu (nhớ các mô tả tệp mở)
    • Xử lý tên tệp không chuẩn
    • Làm thế nào để tiến hành với các tập tin là ổ cắm, đường ống / FIFO, thiết bị khối, thiết bị char? Phải băm chúng là tốt?
    • Không cập nhật thời gian truy cập của bất kỳ mục nào trong khi di chuyển ngang vì đây sẽ là tác dụng phụ và phản tác dụng (trực quan?) Cho một số trường hợp sử dụng nhất định.

Đây là những gì tôi có trên đầu, bất kỳ ai đã dành thời gian làm việc này thực tế sẽ bắt gặp các vấn đề khác về góc và góc.

Đây là một công cụ (từ chối trách nhiệm: Tôi là người đóng góp cho nó) dtreetrawl , rất nhẹ về bộ nhớ, giải quyết hầu hết các trường hợp, có thể hơi thô xung quanh các cạnh nhưng khá hữu ích.

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

Một ví dụ đầu ra thân thiện với con người:

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

Lời khuyên chung luôn được hoan nghênh nhưng câu trả lời tốt nhất là cụ thể và với mã khi thích hợp. Nếu bạn có kinh nghiệm sử dụng công cụ mà bạn tham khảo thì hãy đưa nó vào.
bu5hman

@ bu5hman Chắc chắn! Tôi không thoải mái khi nói (hả hê?) Về việc nó hoạt động tốt như thế nào kể từ khi tôi tham gia vào sự phát triển của nó.
sáu-k

0

Làm riêng cho tất cả các tệp trong mỗi thư mục.

# 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

Di chuyển sang định dạng lưu trữ POSIX ảnh hưởng đến tổng kiểm tra dựa trên GNU Tar

Câu trả lời này được dự định là một bản cập nhật bổ sung cho cách tiếp cận sử dụng đầu ra Tar để băm nội dung của các thư mục, như đã được đề xuất (trong số những điều khác) trong câu trả lời xuất sắc của Warren YoungGilles trước đây.

Kể từ đó, ít nhất openSUSE (kể từ khi phát hành 12.2) đã thay đổi định dạng GNU Tar mặc định của họ từ " định dạng GNU tar 1.13.x" sang định dạng (hơi) vượt trội "POSIX 1003.1-2001 (pax)" . Ngoài ra, ngược dòng (trong số các nhà phát triển GNU Tar) mà họ thảo luận để thực hiện cùng một quá trình di chuyển, xem ví dụ đoạn cuối trên trang này của hướng dẫn GNU Tar :

Định dạng mặc định cho GNU tar được xác định tại thời điểm biên dịch. Bạn có thể kiểm tra nó bằng cách chạy tar --helpvà kiểm tra các dòng cuối cùng của đầu ra. Thông thường, GNU tar được cấu hình để tạo tài liệu lưu trữ ở gnuđịnh dạng, tuy nhiên, phiên bản trong tương lai sẽ chuyển sang posix.

(Trang này cũng đưa ra đánh giá tốt về các định dạng lưu trữ khác nhau có sẵn với GNU Tar.)

Trong trường hợp của chúng tôi, trong đó chúng tôi tar nội dung thư mục và băm kết quả, và không thực hiện các biện pháp cụ thể, một sự thay đổi từ định dạng GNU sang POSIX có các hậu quả sau:

  • Mặc dù nội dung thư mục giống hệt nhau, tổng kiểm tra kết quả sẽ khác nhau.

  • Mặc dù có nội dung thư mục giống hệt nhau, tổng kiểm tra kết quả sẽ khác với chạy để chạy nếu tiêu đề pax mặc định được sử dụng.

Điều thứ hai xuất phát từ thực tế là định dạng POSIX (pax) bao gồm các tiêu đề pax mở rộng được xác định bởi một chuỗi định dạng mặc định %d/PaxHeaders.%p/%ftrong GNU Tar. Trong chuỗi này, trình xác định %pđược thay thế bằng ID tiến trình của quá trình tạo Tar, tất nhiên khác với chạy để chạy. Xem phần này của hướng dẫn GNU Tar và đặc biệt là phần này để biết chi tiết.

Ngay bây giờ, kể từ năm 2019-03-28, có một cam kết được chấp nhận ngược dòng mà từ chối vấn đề này.

Vì vậy, để có thể tiếp tục sử dụng GNU Tar trong trường hợp sử dụng nhất định, tôi có thể đề xuất các tùy chọn thay thế sau:

  • Sử dụng tùy chọn Tar --format=gnuđể nói rõ ràng với Tar để tạo tệp lưu trữ ở định dạng "cũ". Điều này là bắt buộc để xác nhận tổng kiểm tra "cũ".

  • Sử dụng định dạng POSIX mới hơn, nhưng chỉ định rõ ràng một tiêu đề pax phù hợp, ví dụ bằng --pax-option="exthdr.name=%d/PaxHeaders/%f". Tuy nhiên, điều này phá vỡ khả năng tương thích ngược với tổng kiểm tra "cũ".

Đây là một đoạn mã Bash mà tôi sử dụng thường xuyên để tính toán tổng kiểm tra nội dung thư mục bao gồm siêu dữ liệu:

( 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; )

Ở đây, <paths>được thay thế bằng một danh sách các không gian được phân tách bằng dấu cách của tất cả các thư mục mà tôi muốn được bao phủ bởi tổng kiểm tra. Mục đích của việc sử dụng ngôn ngữ C, phân tách tên tệp byte byte và sử dụng find và sort để có được thứ tự độc lập hệ thống tệp của các tệp trong kho lưu trữ đã được thảo luận đầy đủ trong các câu trả lời khác.

Các dấu ngoặc đơn xung quanh giữ cho LC_ALLthiết lập cục bộ trong một khung con.

Ngoài ra, tôi sử dụng biểu thức ! -type svới findđể tránh các cảnh báo từ Tar xảy ra nếu các tệp socket là một phần của nội dung thư mục: GNU Tar không lưu trữ các socket. Nếu bạn muốn được thông báo về các ổ cắm bị bỏ qua, hãy bỏ biểu thức đó đi.

Tôi sử dụng --numeric-ownervới Tar, để có thể xác minh tổng kiểm tra sau này ngay cả trên các hệ thống, nơi không phải tất cả các chủ sở hữu tệp đều biết.

Các --atime-preservelựa chọn cho Tar được bỏ qua tốt hơn nếu bất kỳ của <paths>những lời dối trá trên một thiết bị gắn chỉ đọc. Nếu không, bạn sẽ được cảnh báo cho từng tệp duy nhất có dấu thời gian truy cập Tar không thể khôi phục. Để kích hoạt ghi <paths>, tôi sử dụng tùy chọn này, tốt, để duy trì dấu thời gian truy cập trong các thư mục băm.

Tùy chọn Tar --no-recursion, đã được sử dụng trong đề xuất Gilles , ngăn Tar tự động đệ quy vào các thư mục và để vận hành thay vì tập tin bằng tệp trên bất cứ thứ gì nó được cung cấp từ findđầu ra được sắp xếp .

Và cuối cùng, tôi không sử dụng đúng md5sum: tôi thực sự sử dụng sha256sum.


-1

Nếu bạn không cần md5, bạn có thể thử

find . -type f | xargs cksum | cksum

1
Câu hỏi đặc biệt yêu cầu md5
RalfFriedl
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.