Определите, был ли файл изменен


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, извлечение архива и т. Д.), Проверьте, изменилось ли время его изменения inode ( 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.