Próbuję zaoszczędzić miejsce podczas wykonywania „głupiej” kopii zapasowej, po prostu zrzucając dane do pliku tekstowego. Mój skrypt kopii zapasowej jest wykonywany codziennie i wygląda następująco:
- Utwórz katalog o nazwie od daty kopii zapasowej.
- Zrzuć niektóre dane do pliku tekstowego
"$name"
. - Jeśli plik jest poprawny, gzip go:
gzip "$name"
. W przeciwnym razierm "$name"
.
Teraz chcę dodać dodatkowy krok, aby usunąć plik, jeśli te same dane były również dostępne poprzedniego dnia (i utworzyć dowiązanie symboliczne lub dowiązanie twarde).
Na początku myślałem o użyciu md5sum "$name"
, ale to nie działa, ponieważ przechowuję również nazwę pliku i datę utworzenia.
Czy gzip
istnieje opcja porównania dwóch plików spakowanych gzip i powiedz mi, czy są równe, czy nie? Jeśli gzip
nie ma takiej opcji, czy istnieje inny sposób na osiągnięcie mojego celu?
gzip
file-comparison
Lekensteyn
źródło
źródło
diff <(zcat file1) <(zcat file2)
, ale sugestia mrethubazdiff
wygląda znacznie lepiej.Odpowiedzi:
Możesz użyć
zcmp
lub,zdiff
jak sugeruje mreithub w swoim komentarzu (lub polecenie Kevina, które jest podobne). Będą one stosunkowo nieefektywne, ponieważ faktycznie rozpakowują oba pliki, a następnie przekazują je docmp
lubdiff
. Jeśli chcesz tylko odpowiedzieć „czy oni są tacy sami”, chceszcmp
, będzie znacznie szybciej.Twoje podejście do
md5sum
jest bardzo dobre, ale musisz wziąć MD5 przed uruchomieniemgzip
. Następnie zapisz go w pliku obok.gz
pliku wynikowego . Następnie możesz łatwo porównać plik przed jego skompresowaniem. Jeśli nazwa jest taka sama,md5sum -c
zrób to dla ciebie.I następna kopia zapasowa:
Więc to się nie zmieniło. OTOH, czy to się zmieniło:
Jeśli przejdziesz
--quiet
do niego, otrzymasz kod wyjścia. 0 dla dopasowanych, nie-0 dla różnych.MD5 jest dość szybki, ale nie tak niesamowicie. MD4 (
openssl md4
wydaje mi się, że najlepszy w wierszu poleceń, jest około dwa razy szybszy (ani on, ani MD5 nie są bezpieczne, ale oba są tak samo odporne na kolizje, gdy nikt nie próbuje ich obalić). SHA-1 (sha1sum
) jest bezpieczniejszy, ale wolniejszy; SHA-256 (sha256sum
) jest bezpieczny, ale jeszcze wolniejszy. CRC32 powinien być wielokrotnie szybszy, ale krótszy, a zatem będzie miał więcej losowych kolizji. Jest to również całkowicie niepewne.źródło
zdiff
wydaje się marnotrawstwem, ponieważ chcę tylko wiedzieć, czy plik się zmienił, a nie co .zcmp
wygląda interesująco, spróbuję tego.Odpowiedź @derobert jest świetna, choć chcę podzielić się innymi informacjami, które znalazłem.
gzip -l -v
Pliki skompresowane gzip zawierają już skrót (choć nie jest to bezpieczne, zobacz ten post SO ):
Można połączyć CRC i nieskompresowany rozmiar, aby uzyskać szybki odcisk palca:
cmp
Aby sprawdzić, czy dwa bajty są równe, czy nie, użyj
cmp file1 file2
. Teraz plik spakowany gzip ma nagłówek z dołączonymi danymi i stopką (CRC plus rozmiar oryginalny). Opis formatu gzip pokazuje, że nagłówek zawiera czas, kiedy plik został skompresowany i że nazwa pliku jest ciągiem nul zakończone, który jest dołączany po nagłówku 10 bajtów.Zakładając, że nazwa pliku jest stała i
gzip "$name"
używana jest ta sama komenda ( ), można sprawdzić, czy dwa pliki są różne, używająccmp
i pomijając pierwsze bajty, w tym czas:Uwaga : założenie, że te same opcje kompresji są ważne, w przeciwnym razie polecenie zawsze zgłosi plik jako inny. Dzieje się tak, ponieważ opcje kompresji są przechowywane w nagłówku i mogą wpływać na skompresowane dane.
cmp
po prostu patrzy na surowe bajty i nie interpretuje go jako gzip.Jeśli masz nazwy plików o tej samej długości, możesz spróbować obliczyć bajty, które zostaną pominięte po odczytaniu nazwy pliku. Gdy nazwy plików mają inny rozmiar, możesz uruchomić
cmp
po pominięciu bajtów, npcmp <(cut -b9- file1) <(cut -b10- file2)
.zcmp
Jest to zdecydowanie najlepsza droga, najpierw kompresuje dane i zaczyna porównywać bajty
cmp
(tak naprawdę dzieje się to w skoroszyciezcmp
(zdiff
)).Jedna uwaga, nie bój się następującej uwagi na stronie podręcznika:
Gdy masz wystarczająco nową wersję Bash, kompresja nie użyje pliku tymczasowego, tylko potok. Lub, jak podaje
zdiff
źródło:źródło
gzip -v -l
zgłosi czas pliku zamiast MTIME, jeśli cztery bajty MTIME w nagłówku są równe zero. Zauważ też, że jeśli jest tam MTIME, zwykle trwa to nieco przed czasem pliku, ponieważ to właśnie wtedy rozpoczęła się kompresja.Aby porównać dwa pliki gzip, tylko zawartość, jedno polecenie, nie
diff
, po prostu porównaniemd5sum
Możesz także „filtrować” pod kątem istotnych różnic,
W przypadku skryptów poleciłbym funkcję filtru (nie przetestowano, tylko przykład),
źródło
cmp
.zcat
igrep
można je połączyćzgrep
.zcat
jest po prostugunzip -c
. Użyj odpowiedniego narzędzia do właściwej pracy, KISS jest lepszy niż wzdęcia. W takim przypadku spędziłbym czas na pisaniu czegoś, co w razie potrzeby generuje twarde linki, co sprawia więcej radości.