rsync --상위 대상 폴더로 삭제

rsync --상위 대상 폴더로 삭제

rsync소스 저장소(버전 제어)의 콘텐츠를 공유 NFS 마운트로 동기화하는 프로세스가 있습니다 .

끔찍한 시나리오는 다른 콘텐츠가 다른 소스에서 대상 폴더로 동기화되기 때문에 대상 폴더에 원본 폴더보다 더 많은 콘텐츠가 포함되어 있다는 것입니다. 예를 들어 폴더 구조는 다음과 같습니다.

원천

a/a1.txt
a/a2.txt
b/b1.txt

목적지

a/a1.txt
a/a2.txt
a/a3.txt
b/b1.txt
c/c1.txt

(이 예에서는 다른 곳에서 대상으로 동기화 a/a3.txt됩니다 c/c1.txt. 실제로 여기에는 여러 다른 소스가 포함되며 이에 대한 콘텐츠/프로세스는 영향을 받을 수 없습니다.)

이제 소스 폴더가 a/a2.txt파일을 삭제한다고 가정합니다. 기존 설정을 사용하면 이 파일은 대상에서 삭제되지 않습니다. 그러나 사용하면 --delete다른 파일이 삭제될 수 있으므로 이를 수행하지 않는 것이 필수입니다.

--delete이 rsync에서 어떻게 사용할 수 있지만 요구 사항을 충족합니까? 소스 디렉터리는 버전 관리되기 때문에 이 디렉터리의 전후를 얻는 것이 충분히 간단하므로 원본 소스 디렉터리를 참조로 사용하여 차등 백업을 계산할 수 있지만 이것이 최선의 방법일까요?

답변1

rsync --delete이렇게 사용할 수는 없습니다 . 이는 상태 비저장이며 실행 간에 삭제된 파일에 대한 기록을 유지하지 않습니다. 플래그 --delete는 단순히 rsync소스에 존재하지 않는 대상의 모든 파일을 삭제하도록 지시합니다.

이러한 제한 삭제를 구현하려면 자신의 상태를 유지해야 한다고 생각합니다. 당신을 위해 이 일을 할 수도 없고 rsyncunison수도 없습니다.

다음은 완전한 오류로부터 안전한 솔루션이 아닙니다. 그것은 출발점입니다. (그러나 개행 문자가 포함된 파일을 포함하여 이상한 이름을 가진 파일은 처리합니다.)

두 개의 디렉토리 srcdst. (예제의 목적상 dst로컬인지 원격인지는 실제로 중요하지 않습니다.)

# Find the current list of files (do this just once, to prep the cache)
( cd src && find . -type f -print0 ) | LC_ALL=C sort -z > .state.src

백업을 수행할 때마다 다음 코드를 실행합니다.

# Run the rsync to transfer files. "dst/" could be local
rsync -av src/ remote:dst/

# Determine the set of files to delete in "dst/"
( cd src && find . -type f -print0 ) | LC_ALL=C sort -z | tee .state.src.new |
    LC_ALL=C comm -z - -13 .state.src |
    ssh remote 'while IFS= read -d "" -r f; do rm -f "dst/$f"; done'

# That seemed to work, so update the state cache
[[ 0 -eq $? ]] && mv -f .state.src.new .state.src

내 버전 comm과 같은 버전이 GNU coreutils 8.25보다 이전 버전이고 플래그가 없는 경우 -z다음 대체 해결 방법을 사용할 수 있습니다.

# Find the current list of files (do this just once, to prep the cache)
( cd src && find . -type f -print0 ) | tr '\0\n' '\n\0' | LC_ALL=C sort > .state.src

백업을 수행할 때마다 다음 코드를 실행합니다.

# Run the rsync to transfer files. "dst/" could be local
rsync -av src/ remote:dst/

# Determine the set of files to delete in "dst/"
( cd src && find . -type f  -print0 ) | tr '\0\n' '\n\0' | LC_ALL=C sort | tee .state.src.new |
    LC_ALL=C comm -13 - .state.src |
    tr '\0\n' '\n\0' |
    ssh remote 'while IFS= read -d "" -r f; do rm -f "dst/$f"; done'

# That seemed to work, so update the state cache
[[ 0 -eq $? ]] && mv -f .state.src.new .state.src

관련 정보