Rsync를 사용하여 디렉터리 이동 감지

Rsync를 사용하여 디렉터리 이동 감지

현재 하나의 하드 드라이브를 다른 하드 드라이브(원격이 아닌 로컬)에 백업하는 데 사용하는 명령은 다음과 같습니다.

rsync \
    --info=PROGRESS2,BACKUP,DEL \
    -ab \
    --human-readable \
    --inplace \
    --delete-after \
    --debug=NONE \
    --log-file=/media/blueray/WDPurple/rsync.log \
    --backup-dir=red_rsync_bak.$(date +"%d-%m-%y_%I-%M-%S%P") \
    --log-file-format='%t %f %o %M' \
    --exclude='lost+found' \
    --exclude='.Trash-1000' \
    /media/blueray/WDRed \
    /media/blueray/WDPurple

rsync를 사용하면 --delete-after이동된 디렉터리가 삭제된 것으로 간주되어 생성됩니다.

따라서 소스에서 디렉터리를 이동하면 해당 디렉터리가 대상에서 제거된 다음 소스에서 복사됩니다. 소스에서 큰 디렉토리를 옮기는 경우가 가끔 있기 때문에 시간이 오래 걸리는 경우가 많습니다.

나는 이 문제에 대한 해결책을 거의 찾지 못했습니다.

  1. 패치 rsync.

  2. 패치 없음.

  3. BorgBackup 또는 bup 사용

  4. 사용--fuzzy --delay-updates --delete-delay

그러나 모든 사람에게는 자신만의 문제가 있습니다.

이 패치는 오래 전에 만들어졌기 때문에 최신 rsync에 문제를 일으킬지 잘 모르겠습니다. 또한 패치를 유지 관리하는 것도 어렵습니다.

옵션 2는 내 하드 드라이브를 복잡하게 만듭니다. 또한 더 많은 옵션을 사용했지만 rsync안전한지 확실하지 않습니다.

옵션 3에 관한 한 저는 많은 시간을 투자했으며 rsync지금은 새로운 도구로 전환하고 싶지 않습니다. 또한 이러한 도구에는 고유한 문제가 있습니다.

옵션 4와 관련하여 /test/10GBfile을 사용하여 --fuzzy --delay-updates --delete-delay/test/otherdir/10GBfile_newname으로 이름을 바꾸면 데이터가 동일한 디렉터리에 없기 때문에 여전히 데이터를 다시 보냅니다. 여전히 문제가 많습니다. 전임자. --delay-updates갈등으로 --inplace.

그래서 제가 찾고 있는 해결책은사용--itemize-changes--dry-run이동된 디렉터리 목록을 가져와 대상 mv에서 먼저 실행합니다. (x가 대상의 a/x로 이동하고, y가 대상의 b/y로 이동하고, c/z와 같은 힌트가 있으면 좋을 것입니다. 계속하시겠습니까?) 그런 다음 rsync상단에 언급한 명령을 실행하세요.비슷한 디렉터리와 동일한 이름과 크기를 가진 디렉터리를 고려할 준비가 되었습니다.

디렉토리 트리가 다음과 같다고 가정합니다.

.
├── dest
│   ├── test
│   │   └── empty-asciidoc-document.adoc
│   ├── test2
│   │   └── empty-asciidoc-document.adoc
│   └── test3
│       └── empty-asciidoc-document.adoc
├── src
│   ├── grandpartest1
│   │   └── partest
│   │       └── test1
│   │           └── empty-asciidoc-document.adoc
│   ├── grandpartest2
│   │   └── partest2
│   │       └── test2
│   │           └── empty-asciidoc-document.adoc
│   └── grandpartest3
│       └── partest3
│           └── test3
│               └── empty-asciidoc-document.adoc

디렉토리를 이동하면 --itemize-changes출력은 다음과 같습니다.

% rsync --dry-run -ai --inplace --delete-after /home/blueray/Downloads/src/ /home/blueray/Downloads/dest/
.d..t...... ./
cd+++++++++ grandpartest/
cd+++++++++ grandpartest/partest/
cd+++++++++ grandpartest/partest/test/
>f+++++++++ grandpartest/partest/test/empty-asciidoc-document.adoc
cd+++++++++ grandpartest2/
cd+++++++++ grandpartest2/partest2/
cd+++++++++ grandpartest2/partest2/test2/
>f+++++++++ grandpartest2/partest2/test2/empty-asciidoc-document.adoc
cd+++++++++ grandpartest3/
cd+++++++++ grandpartest3/partest3/
cd+++++++++ grandpartest3/partest3/test3/
>f+++++++++ grandpartest3/partest3/test3/empty-asciidoc-document.adoc
*deleting   test3/empty-asciidoc-document.adoc
*deleting   test3/
*deleting   test2/empty-asciidoc-document.adoc
*deleting   test2/
*deleting   test/empty-asciidoc-document.adoc
*deleting   test/

다음을 사용하여 삭제된 디렉터리를 가져올 수 있습니다.

% echo "$dryrunoutput" | grep "*deleting.*/$" | awk '{print $2}' | while read spo; do echo ${spo%?}; done
test3
test2
test

다음을 사용하여 디렉터리를 추가합니다.

% echo "$dryrunoutput" | grep "cd++.*/$" | awk '{print $2}' | while read spo; do echo ${spo%?}; done | while read spo; do echo ${spo##*/}; done
grandpartest
partest
test
grandpartest2
partest2
test2
grandpartest3
partest3
test3

디렉토리를 추가하고 제거하려면 다음 명령을 사용하십시오.

$ sort  <(echo "$deletedirectories") <(echo "$addeddirectoriesvalue") | uniq -d
test
test2
test3

두 개의 동일한 디렉터리를 비교하려면 디렉터리 크기(바이트)를 사용합니다(대체로 나에게 적합함).

% /usr/bin/du -sb "/home/blueray/Documents/src/test2/test" | grep -oh "^\S*"
4096
% /usr/bin/du -sb "/home/blueray/Documents/dest/test" | grep -oh "^\S*"
4096

지금까지 내가 생각해낸 스크립트는 다음과 같습니다.

#!/bin/bash

source="/media/blueray/WDRed/_working/_scripts/_rsync-test/src/"
destination="/media/blueray/WDRed/_working/_scripts/_rsync-test/dest/"
dryrunoutput=$(rsync --dry-run -ai --inplace --delete-after $source $destination)
deletedirectories=$( echo "$dryrunoutput" | grep "*deleting.*/$" | awk '{print $2}' | while read spo; do echo ${spo%?}; done )
addeddirectorieskey=$( echo "$dryrunoutput" | grep "cd++.*/$" | awk '{print $2}' | while read spo; do echo ${spo%?}; done )
addeddirectoriesvalue=$( echo "$dryrunoutput" | grep "cd++.*/$" | awk '{print $2}' | while read spo; do echo ${spo%?}; done | while read spo; do echo ${spo##*/}; done )

intersection=$( sort  <(echo "$deletedirectories") <(echo "$addeddirectoriesvalue") | uniq -d )

sourcesize=$(/usr/bin/du -sb "${source}test2/test" | grep -oh "^\S*")

destsize=$(/usr/bin/du -sb "${destination}test" | grep -oh "^\S*")

if [[ "$destsize" == "$sourcesize" ]]
then
  mv "${destination}test/" "$destination$addeddirectories"
fi

를 보면 mv "${destination}test/" "$destination$addeddirectories"여기 경로의 일부가 하드코딩되어 있습니다. 또한 다른 문제도 있습니다. 단일 디렉토리 및 이와 유사한 항목에서만 작동합니다.

폴리스티렌비슷한 이름과 크기가 동일하다는 의미는 아니지만 내 경우에는 작동할 것입니다. 내 디렉토리가 주요 문제이고 파일은 그렇지 않습니다. 따라서 파일 이동 감지에 대해서는 크게 걱정하지 않습니다. 나는 디렉토리 이동 감지에만 관심이 있습니다.

답변1

백업의 기초로 사용할 수 있습니다. 소스 및 대상 파일 시스템이 하드 링크된 파일을 처리할 수 있어야 하며 대상 파일이 실행 사이에 작업 디렉터리에 하드 링크된 상태로 남아 있는 것을 신경 쓰지 않아야 합니다. 파일 inode 및 상대 경로를 작성하는 옵션은 findGNU 버전에 따라 다릅니다.-printf

#!/bin/bash
# Usage: [<rsync_args...>] <src> <dst> 
#
args=("$@")
src="${args[-2]}"          # '.'
dst="${args[-1]}"          # eg 'remote:/tmp/dest'
unset args[-1] args[-1]    # Yes really


# Create the working set space
#
temp=".inodes"
mkdir -p "$src/$temp"


# Build the set of files indexed by inode
#
echo Create inodes >&2
find "$src" -path "$src/$temp" -prune -o -type f -printf "%i\t%P\0" |
    while IFS= read -d '' -r line
    do
        inode="${line%%$'\t'*}" file="${line#*$'\t'}"
        ln -f "$src/$file" "$src/$temp/$inode"
    done


# Copy the index and then the full tree
#
echo Copy inodes >&2
rsync -avPR "${args[@]}" "$src/./$temp/" "$dst/"

echo Copy structure >&2
rsync -avHPR --delete-after "${args[@]}" "$src/./$temp/" "$src/./" "$dst/"


# Remove the working set on the source (not essential but you may prefer it)
#
echo Tidyup >&2
rm -rf "$src/$temp"

호출하여 dsync경로에 넣으면 다음과 같이 사용할 수 있습니다.

dsync /media/blueray/WDRed /media/blueray/WDPurple

또는 잠재적으로

dsync --info=PROGRESS2,BACKUP,DEL --backup --human-readable --inplace --delete-after --log-file=/media/blueray/WDPurple/rsync.log --backup-dir=red_rsync_bak.$(date +"%d-%m-%y_%I-%M-%S%P") --log-file-format='%t %f %o %M' --exclude='lost+found' --exclude='.Trash-1000' /media/blueray/WDRed /media/blueray/WDPurple

관련 정보