Xác định xem một tập tin đã được sửa đổi


10

Trong Linux (hiện đang sử dụng hệ thống tệp ext4), làm thế nào người ta có thể kiểm tra nhanh nếu nội dung của tệp đã bị sửa đổi mà không đọc bất kỳ nội dung nào của nó?

statlệnh một cách tiếp cận được đề nghị? Tôi hiện đang làm

$ stat --format "%Y" hello.txt

và sau này tôi có thể kiểm tra xem cùng một lệnh có mang lại cùng một đầu ra không. Nếu vậy, tôi kết luận rằng hello.txt không thay đổi.

Cảm giác của tôi là người ta muốn đưa vào nhiều thông số hơn để chắc chắn hơn. Ví dụ: việc thêm kích thước tệp, tên tệp, v.v., có cung cấp "dấu vân tay" của tệp tốt hơn không?

Về chủ đề này, tôi nhớ lại rằng một khối lượng TrueCrypt mà tôi đã từng bị chương trình sao lưu gia tăng của tôi bỏ qua, có thể là do TrueCrypt đảm bảo không để lại thay đổi dữ liệu meta. Tôi cho rằng thực sự có thể thay đổi tất cả dữ liệu được trả về stat, do đó không thể đảm bảo nhận được mọi sửa đổi có thể của tệp?


md5sum filename?
Ramesh

md5sumhoặc bất kỳ loại tổng kiểm tra đọc nội dung của tệp. Tôi không muốn làm điều đó vì nó quá chậm so với mục đích của tôi.
DustByte

ls -tsẽ sắp xếp nội dung trong một thư mục theo thời gian sửa đổi.
ryekayo

"đã được sửa đổi"? Mỗi tập tin đã được sửa đổi, câu hỏi là khi nó được sửa đổi. Bạn có thể sử dụng 'find' để tìm kiếm một phạm vi thời gian sửa đổi cụ thể.
Ray Andrew

Câu trả lời:


5

Nếu bạn muốn phát hiện xem một tệp đã được sửa đổi thông qua các phương tiện thông thường (chỉnh sửa nó trong một số ứng dụng, kiểm tra phiên bản mới từ các hệ thống kiểm soát sửa đổi, xây dựng lại, v.v.), hãy kiểm tra xem thời gian sửa đổi của nó (mtime) có thay đổi từ kiểm tra cuối cùng. Đó là những gì stat -c %Ybáo cáo.

Thời gian sửa đổi có thể được thiết lập bằng touchlệnh. Nếu bạn muốn phát hiện xem tập tin đã thay đổi theo bất kỳ cách nào (bao gồm cả việc sử dụng touch, trích xuất một kho lưu trữ, v.v.), hãy kiểm tra xem thời gian thay đổi inode ( ctime ) của nó có thay đổi so với lần kiểm tra trước không. Đó là những gì stat -c %Zbáo cáo. Thời gian không thể bị giả mạo ngoại trừ bởi quản trị viên hệ thống (và thậm chí sau đó, chỉ thông qua các phương tiện gián tiếp: bằng cách thay đổi đồng hồ hệ thống hoặc bằng cách truy cập trực tiếp vào đĩa, bỏ qua hệ thống tệp).


Cảm ơn, tôi tập hợp rằng ctime là những gì tôi nên sử dụng. Nó không tuân theo câu hỏi của tôi rằng mục đích của việc này là sử dụng nó trong tập lệnh sao lưu của riêng tôi, nơi tổng kiểm tra sẽ chỉ được tính cho các tệp mới hoặc các tệp đã thay đổi. Tôi có thể đủ khả năng tính toán tổng kiểm tra cho các tệp đã thay đổi chỉ "một chút", nói rằng các quyền đã thay đổi, v.v. Tôi thích càng gần càng tốt để thực sự nhìn vào nội dung của tệp để xác định thay đổi.
DustByte

3

Lệnh stat chỉ có độ phân giải của một giây. Vì vậy, nếu tệp được sửa đổi hai lần trong cùng một giây, bạn có thể bỏ lỡ một sửa đổi. Các hệ thống tệp mới hơn như ext4 cung cấp dấu thời gian có độ phân giải cao hơn tính bằng nano giây, nhưng một số công cụ cũ chưa bắt kịp.

Ngoài ra, các chương trình khác có thể đặt thời gian sửa đổi tùy ý. Bạn có thể thấy làm thế nào điều này có thể xảy ra thông qua lệnh cảm ứng.

Nếu bạn lo lắng về một trong hai khả năng đó thì cũng không nên xem xét kích thước tệp. Đây là những gì rsync làm khi tìm kiếm các tệp sửa đổi.


1

Cảm giác của tôi là người ta muốn đưa vào nhiều thông số hơn để chắc chắn hơn.

Những gì bạn có là phương pháp chính xác. Lý do duy nhất để thất bại là nếu hệ thống tập tin không cập nhật đúng cách - trong trường hợp đó bạn sẽ phải chịu một loạt các vấn đề nghiêm trọng hơn.

Tất nhiên, tôi cho rằng ai đó có kiến ​​thức phù hợp và quyền truy cập root vào hệ thống có thể truy cập phân vùng có thể thay đổi thông tin để làm cho nó trông như thể tệp đã bị thay đổi. Tuy nhiên, trong trường hợp này chắc chắn họ đã chắc chắn làm tương tự với kích thước, v.v.


0

Tôi làm cho dấu vân tay chi tiết hơn.

Tôi đã tạo một hàm bao bọc nhỏ để tạo đầu ra giống hệt nhau cho cả hai phiên bản MacOS / BSD và GNU của stat(cũng phát hiện phiên bản cài đặt Homebrew có gtiền tố).

init() {
  if command -v gstat > /dev/null; then
    # GNU coreutils with g prefix.
    statCmdArgs=("gstat" "--format=%n %s %b %u %g %i %h %Y %Z %W %o");
  elif ! stat --version > /dev/null 2> /dev/null; then
    # MacOS/BSD stat
    statCmdArgs=("stat" "-f" "%N %z %b %u %g %i %l %m %c %B %k");
  else
    # Assume GNU version without prefix.
    statCmdArgs=("stat" "--format=%n %s %b %u %g %i %h %Y %Z %W %o");
  fi;
}

getFileStatus() {
  "${statCmdArgs[@]}" "$1";
}

Các initchức năng được gọi là một lần trong kịch bản khởi tạo và getFileStatuscó thể được gọi nhiều lần mà không có chi phí phát hiện.

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.