Визначте, чи файл було змінено


10

Як в Linux (зараз використовується файлова система ext4), як можна швидко перевірити, чи змінено вміст файлу, не читаючи жодного його вмісту?

Чи є statкоманда рекомендованим підходом? Я зараз роблю

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

і пізніше я можу перевірити, чи однакова команда дає той самий вихід. Якщо це так, я роблю висновок, що hello.txt не змінився.

Я відчуваю, що хочеться ввести більше параметрів, щоб бути ще більш впевненим. Наприклад, чи додавання розміру файлу, імені файлу тощо, забезпечить ще кращий "відбиток" файлу?

У цій темі я пам'ятаю, що тома TrueCrypt, яку я колись мав, завжди ігнорувалась моєю додатковою програмою резервного копіювання, можливо, тому, що TrueCrypt переконався не залишати позаду ніяких метаданих змін. Я припускаю, що дійсно можливо змінити всі дані, що повертаються stat, отже, не можна гарантувати, що можна буде отримати будь-яку можливу модифікацію файлу?


md5sum filename?
Рамеш

md5sumабо будь-яка контрольна сума читає вміст файлу. Я не хочу цього робити, оскільки це занадто повільно для моїх цілей.
DustByte

ls -tбуде сортувати вміст у каталозі за часом модифікації.
ryekayo

"було змінено"? Кожен файл був модифікований, питання - коли він був змінений. Ви можете використовувати "знайти" для пошуку певного діапазону часу модифікації.
Рей Ендрюс

Відповіді:


5

Якщо ви хочете виявити, чи був файл модифікований звичайними засобами (редагування його в якійсь програмі, перевірка нової версії з систем управління ревізією, відновлення її тощо), перевірте, чи змінився час її модифікації (mtime) від остання перевірка. Ось що stat -c %Yповідомляє.

Час модифікації може бути встановлений touchкомандою. Якщо ви хочете виявити, чи змінився файл якимось чином (включаючи використання touch, вилучення архіву тощо), перевірте, чи змінився його час зміни вкладу ( ctime ) від останньої перевірки. Ось що stat -c %Zповідомляє. Ctime не може бути підроблений, за винятком системного адміністратора (і навіть тоді, лише непрямими способами: зміною системного годинника або прямим доступом до диска в обхід файлової системи).


Дякую, я вважаю, що ctime - це те, що я повинен використовувати. З мого питання не випливало, що метою цього є використання його в моєму власному резервному скрипті, де контрольні суми будуть обчислюватися лише для нових файлів або файлів, які змінилися. Я можу дозволити собі обчислювальні контрольні суми для файлів, які просто "трохи змінилися", скажімо, дозволи змінилися і т. Д. Я вважаю за краще якомога ближче до фактичного перегляду вмісту файлу для визначення зміни.
DustByte

3

Команда stat має лише роздільну здатність секунди. Отже, якщо файл був змінений двічі за одну і ту ж секунду, ви можете пропустити модифікацію. Більш нові файлові системи на зразок ext4 забезпечують часові позначки більш високої роздільної здатності в наносекундах, але деякі старі інструменти ще не досягли.

Також для інших програм можливо встановити довільний час модифікації. Ви можете бачити, як це може статися за допомогою сенсорної команди.

Якщо ви турбуєтеся про будь-яку з цих двох можливостей, було б непогано також переглянути розмір файлу. Це те, що робить rsync, коли шукає модифіковані файли.


1

Я відчуваю, що хочеться ввести більше параметрів, щоб бути ще більш впевненим.

У вас є правильний метод. Єдиною причиною цього не вдалося б, якщо файлова система не оновлюється належним чином - у цьому випадку у вас виникне ціла купа більш серйозних проблем.

Звичайно, я припускаю, що хтось із правильними знаннями та кореневим доступом до системи, де доступний розділ, може змінити інформацію, щоб вона виглядала так, ніби файл не змінений. Однак у цьому випадку вони, безумовно, переконалися б зробити те саме з розміром тощо.


0

Я роблю відбиток пальця більш детальним.

Я зробив невелику функцію обгортки, яка генерує ідентичний вихід для версій MacOS / BSD і GNU stat(також виявляє встановлену Homebrew версію з gпрефіксом).

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";
}

Ця initфункція викликається один раз під час ініціалізації сценарію і getFileStatusможе бути викликана повторно, без накладного виявлення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.