Sprawdź, czy plik został zmodyfikowany

10

Jak w systemie Linux (obecnie korzystającym z systemu plików ext4) można szybko sprawdzić, czy zawartość pliku została zmodyfikowana bez odczytywania jej zawartości?

Czy statpolecenie jest zalecanym podejściem? Obecnie to robię

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

a później mogę sprawdzić, czy to samo polecenie daje takie same wyniki. Jeśli tak, dochodzę do wniosku, że hello.txt się nie zmieniło.

Mam wrażenie, że chce się wprowadzić więcej parametrów, aby być jeszcze bardziej pewnym. Na przykład, czy dodanie rozmiaru pliku, nazwy pliku itp. Zapewniłoby jeszcze lepszy „odcisk palca” pliku?

W tym temacie przypominam sobie, że wolumin TrueCrypt, który kiedyś miałem, był zawsze ignorowany przez mój program do tworzenia przyrostowych kopii zapasowych, prawdopodobnie dlatego, że TrueCrypt upewniał się, że nie pozostawia żadnych zmian w metadanych. Przypuszczam, że rzeczywiście można zmienić wszystkie dane zwrócone przez stat, a zatem nie można zagwarantować, że zostaną pobrane przy każdej możliwej modyfikacji pliku?

DustByte
źródło
md5sum filename?
Ramesh
md5sumlub jakakolwiek suma kontrolna odczytuje zawartość pliku. Nie chcę tego robić, ponieważ jest to zbyt wolne dla moich celów.
DustByte
ls -tposortuje zawartość w katalogu według czasu modyfikacji.
ryekayo
„został zmodyfikowany”? Każdy plik został zmodyfikowany, pytanie brzmi, kiedy został zmodyfikowany. Możesz użyć „znajdź”, aby wyszukać określony zakres czasów modyfikacji.
Ray Andrews,

Odpowiedzi:

5

Jeśli chcesz wykryć, czy plik został zmodyfikowany w zwykły sposób (edytując go w niektórych aplikacjach, sprawdzając nową wersję z systemów kontroli wersji, odbudowując go itp.), Sprawdź, czy czas modyfikacji (mtime) zmienił się z ostatnia kontrola. To właśnie stat -c %Yraporty.

Czas modyfikacji można ustawić za pomocą touchpolecenia. Jeśli chcesz wykryć, czy plik zmienił się w jakikolwiek sposób (w tym użycie touch, rozpakowanie archiwum itp.), Sprawdź, czy jego czas zmiany i-węzła ( ctime ) zmienił się od ostatniego sprawdzenia. To właśnie stat -c %Zraporty. Ctime nie może zostać sfałszowany, chyba że przez administratora systemu (a nawet wtedy tylko pośrednio: poprzez zmianę zegara systemowego lub bezpośredni dostęp do dysku, z pominięciem systemu plików).

Gilles „SO- przestań być zły”
źródło
Dzięki, rozumiem, że powinienem użyć ctime. Z mojego pytania nie wynikało, że celem tego jest użycie go we własnym skrypcie kopii zapasowej, w którym sumy kontrolne będą obliczane tylko dla nowych plików lub plików, które uległy zmianie. Mogę sobie pozwolić na obliczanie sum kontrolnych dla plików, które zmieniły się tylko „nieznacznie”, powiedzmy, że uprawnienia uległy zmianie itp. Wolę być tak blisko, jak to możliwe, zamiast patrzeć na zawartość pliku w celu ustalenia zmiany.
DustByte,
3

Polecenie stat ma rozdzielczość tylko sekundy. Więc jeśli plik został zmodyfikowany dwukrotnie w tej samej sekundzie, możesz pominąć modyfikację. Nowsze systemy plików, takie jak ext4, zapewniają znaczniki czasu o wyższej rozdzielczości w nanosekundach, ale niektóre ze starych narzędzi jeszcze nie nadrobiły zaległości.

Możliwe jest również, że inne programy ustawią arbitralny czas modyfikacji. Możesz zobaczyć, jak to się dzieje za pomocą polecenia dotykowego.

Jeśli martwisz się którąś z tych dwóch możliwości, nie byłoby złym pomysłem przyjrzenie się również rozmiarowi pliku. To właśnie robi rsync, gdy szuka zmodyfikowanych plików.

Steve Sether
źródło
1

Mam wrażenie, że chce się wprowadzić więcej parametrów, aby być jeszcze bardziej pewnym.

To, co masz, to właściwa metoda. Jedynym powodem tego niepowodzenia byłoby niepoprawne aktualizowanie systemu plików - w takim przypadku wystąpi cała masa poważniejszych problemów.

Oczywiście zakładam, że ktoś z odpowiednią wiedzą i dostępem root do systemu, w którym partycja jest dostępna, może zmienić informacje, aby wyglądały tak, jakby plik nie został zmieniony. Jednak w tym przypadku z pewnością zrobiliby to samo z rozmiarem itp.

Złotowłosa
źródło
0

Sprawiam, że odcisk palca jest bardziej szczegółowy.

Zrobiłem małą funkcję otoki, która generuje identyczne wyjście zarówno dla wersji MacOS / BSD, jak i GNU stat(wykrywa również wersję zainstalowaną Homebrew z gprefiksem).

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

initFunkcja jest wywoływana raz w czasie inicjalizacji skryptu i getFileStatusmoże być wielokrotnie nazywany bez narzutu detekcji.

devstuff
źródło