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

2つの同じディレクトリを比較するには、ディレクトリサイズ(バイト)を使用します(代わりに私に適しています)。

% /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

関連情報