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 -s
chỉ 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 -s
bằng một cuộc gọi đến sort
. Các -k 2
chú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 sort
cuộc gọi. Các find -s
biế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 ls
và như vậy, mà âm thầm sắp xếp nội dung thư mục cho bạn. find
không có -s
hoặc một sort
cuộ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 md5sum
lệnh thành md5
hoặ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 sort
lệ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à sum
chương trình Unix cũ .
Phương pháp này có phần không hiệu quả, gọi md5sum
N + 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 và 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ì tar
cũ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 find
phương thức dựa trên, tar
sẽ 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 | cpio
tùy chọn trong câu trả lời của Gilles .
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 :-)