저는 단순히 데이터를 텍스트 파일에 덤프하여 "멍청한" 백업을 만드는 동안 공간을 절약하려고 합니다. 내 백업 스크립트는 하루에 한 번 실행되며 다음과 같습니다.
- 백업 날짜를 따서 이름이 지정된 디렉터리를 만듭니다.
- 일부 데이터를 텍스트 파일로 덤프합니다
"$name"
. - 파일이 유효하면 gzip으로 압축하세요:
gzip "$name"
. 그렇지 않으면,rm "$name"
.
이제 전날에도 동일한 데이터가 있었다면 파일을 삭제하는 추가 단계를 추가하고 싶습니다(그리고 심볼릭 링크나 하드 링크를 생성).
처음에는 을 사용하려고 생각했지만 md5sum "$name"
파일 이름과 생성 날짜도 저장하기 때문에 작동하지 않습니다.
gzip
두 개의 gzip 파일을 비교하여 동일한지 알려주는 옵션이 있나요 ? 그러한 옵션이 없다면 gzip
목표를 달성할 수 있는 다른 방법이 있습니까?
답변1
@덕로버트훌륭한 답변이지만 제가 찾은 추가 정보를 공유하고 싶습니다.
gzip -l -v
gzip 압축 파일에는 이미 해시가 포함되어 있습니다(안전하지는 않지만이 게시물):
$ echo something > foo
$ gzip foo
$ gzip -v -l foo.gz
method crc date time compressed uncompressed ratio uncompressed_name
defla 18b1f736 Feb 8 22:34 34 10 -20.0% foo
CRC와 압축되지 않은 크기를 결합하여 신속하게 지문을 얻을 수 있습니다.
gzip -v -l foo.gz | awk '{print $2, $7}'
CMP
2바이트가 같은지 확인하려면 를 사용하세요 cmp file1 file2
. 이제 gzip 압축 파일에는 데이터와 바닥글(CRC + 원본 크기)이 추가된 헤더가 있습니다. 이것gzip 형식에 대한 설명표시 헤더에는 파일이 압축된 시간이 포함되어 있으며 파일 이름은 10바이트 헤더에 추가된 null로 끝나는 문자열입니다.
따라서 파일 이름이 변경되지 않고 gzip "$name"
동일한 명령( )을 사용한다고 가정하면 cmp
시간을 포함한 첫 번째 바이트를 사용하고 건너뛰면 두 파일이 서로 다른지 확인할 수 있습니다.
cmp -i 8 file1 file2
노트: 동일한 압축 옵션을 가정하는 것이 중요합니다. 그렇지 않으면 명령이 항상 파일을 다르게 보고합니다. 이는 압축 옵션이 헤더에 저장되어 압축된 데이터에 영향을 미칠 수 있기 때문에 발생합니다. cmp
원시 바이트만 보고 gzip으로 해석하지 않습니다.
동일한 길이의 파일 이름이 있는 경우 파일 이름을 읽은 후 건너뛸 바이트 수를 계산해 볼 수 있습니다. 파일 이름의 크기가 다른 경우 cmp
바이트를 건너뛴 후 실행할 수 있습니다 cmp <(cut -b9- file1) <(cut -b10- file2)
.
지캅
이것은 확실히 가장 좋은 접근 방식입니다. 먼저 데이터를 압축하고 바이트 비교를 시작합니다(실제로 이는 cmp
( ) 쉘 스크립트에서 수행되는 작업입니다).zcmp
zdiff
맨 페이지에 있는 다음 설명을 두려워하지 마십시오.
비교하기 전에 두 파일의 압축을 풀어야 하는 경우 두 번째 파일은 /tmp로 압축이 풀립니다. 다른 모든 경우에는 zdiff 및 zcmp는 파이프만 사용합니다.
충분히 새로운 Bash가 있으면 압축은 임시 파일을 사용하지 않고 파이프만 사용합니다. 또는 zdiff
소스에 따르면 다음과 같습니다.
# Reject Solaris 8's buggy /bin/bash 2.03.
답변2
mreithub가 그의 의견(또는 Kevin의 명령과 유사)에서 제안한 대로 zcmp
or를 사용할 수 있습니다 . zdiff
이는 실제로 두 파일의 압축을 푼 다음 cmp
또는 에 전달하기 때문에 상대적으로 비효율적입니다 diff
. "그들은 동일합니까"라고 대답하고 싶다면 cmp
훨씬 더 빨라질 것입니다.
귀하의 방법은 md5sum
매우 훌륭하지만 MD5를 수강해야 합니다.앞으로달리기 gzip
. 그런 다음 생성된 파일과 함께 파일에 저장합니다 .gz
. 그러면 파일을 압축하기 전에 쉽게 비교할 수 있습니다. 이름이 동일하면 md5sum -c
이 작업이 수행됩니다.
$ mkdir "backup1"
$ cd backup1
$ echo "test" > backup-file
$ md5sum backup-file > backup-file.md5
$ gzip -9 backup-file
다음 백업은 다음과 같습니다.
$ mkdir "backup2"
$ cd backup2
$ echo "test" > backup-file
$ md5sum -c ../backup1/backup-file.md5
backup-file: OK
그래서 그것은 변하지 않았습니다. OTOH, 변경된 경우:
$ echo "different" > backup-file
$ md5sum -c ../backup1/backup-file.md5
backup-file: FAILED
md5sum: WARNING: 1 computed checksum did NOT match
--quiet
이를 전달한 경우 에만 종료 코드를 제공합니다. 0은 일치를 의미하고, 0이 아닌 경우는 다름을 의미합니다.
MD5는 꽤 빠르지만 그렇게 빠르지는 않습니다. MD4( openssl md4
명령줄에서 얻은 것 중 최고라고 생각합니다)는 약 두 배 빠릅니다(MD5도 안전하지 않지만 둘 다 아무도 깨지려고 하지 않을 때 충돌 방지 기능이 있습니다). SHA-1( sha1sum
)은 더 안전하지만 느립니다. SHA-256( sha256sum
)은 안전하지만 여전히 느립니다. CRC32는 몇 배 더 빠르지만 길이가 더 짧아서 무작위 충돌이 더 많이 발생합니다. 또한 완전히 안전하지 않습니다.
답변3
두 개의 gzip 파일을 비교하려면 내용만, 하나의 명령, no diff
, 그냥 비교하세요.md5sum
$ diff -q <(zcat one.gz|md5sum|cut -f1 -d' ') \
<(zcat two.gz|md5sum|cut -f1 -d' ') \
&& echo same || echo not_same
관련 차이점을 "필터링"할 수도 있습니다.
$ diff -q <(zcat one.gz|grep -v '^-- Dump completed'|md5sum|cut -f1 -d' ') \
<(zcat two.gz|grep -v '^-- Dump completed'|md5sum|cut -f1 -d' ') \
&& echo same || echo not_same
스크립트를 작성하는 경우 필터 기능을 사용하는 것이 좋습니다(테스트되지 않음, 예시일 뿐임).
do_filter_sum() {
zcat $1 | grep -v '^-- Dump completed' | md5sum | cut -f1 -d' '
}
diff -q <(do_filter_sum one.gz) \
<(do_filter_sum two.gz) \
&& echo same || echo not_same