예를 들어 전체 디렉터리를 다음과 같은 구조를 가진 새 디렉터리(예:)로 미러링하는 가장 좋은 방법 original/
은 무엇입니까?mirror/
mirror/data/
mirror/tree/
- 디렉토리 또는 하위 디렉토리
original/
의 모든 파일은 하드 링크되어 있습니다.문서존재하다mirror/data
- 파일 이름은 콘텐츠의 해시와 같은 콘텐츠의 고유 식별자입니다.
mirror/tree
에서 원본 파일의 상대 경로와 상대 경로가 일치하는 지점부터 시작하여 심볼릭 링크됩니다original
.
쉽게 복원할 수 있도록?
이 기능을 기존 도구로 구현할 수 있습니까? – 파일 내용을 기반으로 고유 식별자를 생성하기 위해 명령을 유연하게 선택할 수 있는 명령입니다.
예를 들어 파일이 하나만 있고 original/something
"data"라는 단어가 포함된 텍스트 파일이라고 가정합니다. 그런 다음 스크립트나 명령을 실행 original
하고 결과는 다음과 같습니다.
$ tree original mirror
original
└── something
mirror
├── data
│ └── 6667b2d1aab6a00caa5aee5af8…
└── tree
└── original
└── something -> ../../data/6667b2d1aab6a00caa5aee5af8…
5 directories, 3 files
여기서 파일 667b…
은 하드 링크 original/something
이고 해당 파일 이름은 파일의 sha256sum 해시입니다. 가독성을 위해 파일명을 축약하였으니 참고하시기 바랍니다.
거울을 통해 원래의 모습을 완벽하게 재현하고 싶었습니다.
이 작업을 수행하기 위해 스크립트를 작성할 수 있다는 것을 알고 있지만 그렇게 하기 전에 실수를 하고 일부 데이터가 손실될 수 있으며 이미 이 작업을 안전하게 수행하는 도구가 있는지 알고 싶습니다. ) 멀리) 또는 함정이 있는 경우.
배경: 이름이 변경된 디렉토리를 추적하는 아카이브를 유지하고 싶지만 버전 제어가 필요하지 않습니다. git-annex
Git 저장소를 사용하는 데 많은 오버헤드가 있다는 것을 알고 있지만 디렉터리의 내용을 파일 이름이 해당 내용의 해시인 파일로 미러링하려면 디렉터리 구조에 대한 심볼릭 링크를 사용해야 합니다. 그런 다음 git-diff를 사용하여 이름 변경을 추적할 수 있습니다. 나는 git-annex가 무엇을 하는지 완전히 이해하지 못하기 때문에 내 데이터를 보관하는 것을 신뢰하고 싶지 않습니다. 그래서 저는 더 가볍고 덜 방해가 되는 대안을 찾고 있습니다.
답변1
구현하는 것은 그리 어렵지 않습니다. GNU 시스템( ln -r
및 sha1sum -z
) 및 다음과 함께 zsh
:
mkdir -p mirror/{data,tree} &&
find original -type f -exec sha1sum -z {} + |
while IFS= read -rd '' rec; do
sum=$rec[1,40] file=$rec[43,-1]
ln -f -- $file mirror/data/$sum &&
mkdir -p -- mirror/tree/${${file#*/}:h} &&
ln -rs mirror/data/$sum mirror/tree/${file#*/}
done
디렉터리의 메타데이터(소유권, 권한, mtime/atime, ACL, 확장 속성)를 보존하려고 시도하지 않습니다. 여러 파일의 내용이 동일한 경우 연결하게 되는 파일은 보고되는 순서(정의되지 않음) mirror/data
에 따라 달라지기 때문에 다소 무작위가 됩니다 .find
또한 빈 디렉터리와 디렉터리나 일반 파일이 아닌 파일(예: 심볼릭 링크, fifos, 장치...)은 복사되지 않습니다.
GNU를 사용하여 특수 파일과 가능한 많은 메타데이터를 포함하는 디렉토리 구조를 복사할 수 있습니다 tar
.
set -o pipefail
mkdir -p mirror/{data,tree} &&
(
cd original && find . ! -type f -print0 |
tar -cf - --xattrs --null --verbatim-files-from --no-recursion -T -
) | (
cd mirror/tree && tar -xpf - --xattrs
) &&
find original -type f -exec sha1sum -z {} + |
while IFS= read -rd '' rec; do
sum=$rec[1,40] file=$rec[43,-1]
ln -f -- $file mirror/data/$sum &&
ln -rs mirror/data/$sum mirror/tree/${file#*/}
done
그러나 이러한 디렉토리에 이러한 기호 링크를 생성하면 마지막 수정 시간이 업데이트됩니다.