
バックアップツールを使用する場合duplicity
、私は気づいた。ソースからファイルの名前を変更すると、データはネットワーク経由でターゲットに転送されます。、ちょっと残念です。内部duplicity
使用のためにlibrsync
見てみることにしましたrsync
。
これ建築wikiページ状態:
ハンドルの名前変更
移動または名前変更されたファイルは検出され、2回保存または転送されません。これは通常、ファイルまたはそのブロックのチェックサムを計算することを意味します。この機能が不足しているアプリケーションは、次の機能を組み合わせて補完することができます。hsync
AUR、同期名変更専用です。
rsync: ハンドルの名前変更: いいえ
これが本当に意味するのは、使用時にrsync
10GBがネットワーク経由で宛先に再送信されるのを防ぐ方法はありません。、ソースマシンの名前を次のように変更すると/test/10GBfile
?/test/10GBfile_newname
の長い人気を考えると、rsync
これを処理するより良い方法はありますか?
答え1
rsync
実行時以外は状態を維持しないため、名前の変更を追跡するメカニズムはありません。元のマシンでに名前を変更すると、デフォルトでは/test/10GBfile
削除されたアイテムと生成されたアイテムのみが表示されます。/test/10GBfile_newname
rsync
10GBfile
10GBfile_newname
パラメータ--fuzzy
()は、ターゲット上の潜在的なデータソース-y
を識別するのに役立ち、ファイルコピーの代わりにネットワークコピーを防ぐことができます。ただし、(ほとんど)ファイルの一致のみを考慮できます。10GBfile
10GBfile_newname
同じディレクトリにしたがって、あなたの例は一致しますが、名前を変更/test/10GBfile
すると/test/otherdir/10GBfile_newname
そうではありません。
また、マニュアル(man rsync
)は、使用する予定の場合、または使用する前に潜在的な一致が削除されないように使用する--delete
必要があることを示唆しています。--delay-updates
--delete-after
--fuzzy
はい
# Prepare an uncompressible 100MB file
mkdir -p /tmp/test
dd bs=1M count=100 iflag=fullblock if=/dev/urandom >/tmp/test/file1
# Normal first-time copy
rsync -av --fuzzy --delete-after /tmp/test/ remote:/tmp/test
# Skip copy because unchanged
rsync -av --fuzzy --delete-after /tmp/test/ remote:/tmp/test
# Rename file (per your example)
mv /tmp/test/file1 /tmp/test/file2
# Fast copy because fuzzy match
rsync -av --fuzzy --delete-after /tmp/test/ remote:/tmp/test
進行状況のブロック固有の詳細を表示するには、2つの-v
フラグ(たとえば)を追加します。rsync -avvv …
答え2
--fuzzy
すでに答えを受けていますが、ハードリンクに関連する別の興味深いハッキングがあります。
最初の送信後
$ rsync -avHP --delete-after ~/family/Photos remotebox:backups
作業ディレクトリへのハードリンクを作成します。
$ cd ~/family
$ cp -rlp Photos Photos-work
その後利用できます
$ rsync -avHP --delete-after --no-inc-recursive ~/family/Photos ~/family/Photos-work remotebox:backups
新しい構造をリモコンに転送します。
その理由とその仕組みは次のとおりです。
https://lincolnloop.com/blog/Detecting-file-moves-renames-rsync/
答え3
そのページにオプションパッチが--detect-renamed
使用できると主張しますrsync 3.0.9
。ここにはパッチへのリンクがあります。バグジラ議論。私は選択の余地rsync 3.1.3
がありませんでした--detect-renamed
。言及された議論は現在進行中です:
2021-01-15 14:19:12 UTC時間
この機能要求は古すぎて、btrfs / zfs / etcがrsyncよりも最適化されたバックアップソリューションであるため、関連性が失われました。
一部の人々は「関連性の喪失」に同意しないし、私は同意しない人々の意見に同意します。
それクレジットページ主張する:
btrfs syncはこの機能をサポートしていますが、両端にbtrfsが必要です。
私が考えるものエイラトラット話す。
以下は私の現在のソリューションです(git
私の考えでは少し過剰だと思います)。
私の具体的な状況:私は名前を頻繁に変更せず、バックアップではなく同期リンク(1対1ではない)が欲しいです。そのためmv
、rsyncを前後に実行するために、元々作成したスクリプトによってさらに実行されるコマンド(最後に新しいコマンドを追加)を作成するシェルコマンドファイルを作成することにしました。このスクリプトは多くのテストを受けていないため、リスクを取って実行する必要があり、改善のための提案を歓迎します。 rsync--detect-renamed
オプションがまもなくリリースされることを願っています。
次のスクリプト全体は、同期の一方のシェルファイルサイズが他方のシェルファイルよりも大きい場合は別々に処理し、わからないため、いくつかのチェックが含まれているため、かなり長いです(最近開始したため)。このスクリプトを使用して)comm
プログラムかどうか正しく見つかった唯一の行は、おそらく「ソートされた」(マンページ別)ファイルに適用されることです。鍵は次のとおりです。
# do renames / moves at both ends
cd $remote_path
bash -c "$(comm --nocheck-order -3 -1 $f_RE $f_LO)"
cd $local_path
bash -c "$(comm --nocheck-order -3 -2 $f_RE $f_LO)"
# merge files via temp file
(comm --nocheck-order -1 -2 $f_LO $f_RE) > $f_LO.3
(comm --nocheck-order -3 -1 $f_RE $f_LO) >> $f_LO.3
(comm --nocheck-order -3 -2 $f_RE $f_LO) >> $f_LO.3
cp $f_LO.3 $f_RE
mv $f_LO.3 --force $f_LO
rm $f_LO.1 $f_LO.2
フルシェル機能:
#!/bin/bash
do_sync(){
if [ -d $remote_path ]; then
# ===== workaround for renaming / moving (run manually made commands before rsync) ===== #
# man comm: comm - compare two sorted files line by line
complex_flag=0 # later set by script to 1 if changes identified from both sync directions
to_rsync=1 # to run rsync by default
f_RE=$remote_path/_rename_move.sh
f_LO=$local_path/_rename_move.sh
if [ -f $f_RE ]; then
if [ -f $f_LO ]; then
# if both exist, -gt greated than, stat --printf="%s" size in bytes
if [ $(stat --printf="%s" $f_RE) -gt $(stat --printf="%s" $f_LO) ]; then
# small file (2nd) is fully contained in the beginning of larger file (maybe test binary mode more efficient)
# -1 suppress column 1 (lines unique to FILE1) : man comm
if [ -z "$(comm --nocheck-order -3 -1 $f_RE $f_LO)" ]; then
# run only additional commands
cd $local_path
bash -c "$(comm --nocheck-order -3 -2 $f_RE $f_LO)"
# overwrite small with larger one
cp $f_RE $f_LO
else complex_flag=1; fi
# remote smaller than local
elif [ $(stat --printf="%s" $f_RE) -lt $(stat --printf="%s" $f_LO) ]; then
# small file (1nd) is fully contained in the beginning of larger file (maybe test binary mode more efficient)
if [ -z "$(comm --nocheck-order -3 -2 $f_RE $f_LO)" ]; then
# run only additional commands
cd $remote_path
bash -c "$(comm --nocheck-order -3 -1 $f_RE $f_LO)"
# overwrite small with larger one
cp $f_LO $f_RE
else complex_flag=1; fi
# same size but different contents
elif [ ! $(sha256sum $f_RE | awk '{ print $1 }') = $(sha256sum $f_LO | awk '{ print $1 }') ]; then
complex_flag=1;
fi
# nothing to do if files are the same
# if only remote exists
else
cd $local_path && $f_RE
fi
# neither file was found to be part of another as a whole
# expect changes (moves/renames) from both ends
if [ $complex_flag -eq 1 ]; then
# doing echo "$()" removes trailing empty lines compared to for some reason (TODO why?)
# check that doing symmetrically with appending to local results in same number of lines in a file
# and selecting matching in both and adding distinct from both too results in same number of lines in a file
cp $f_RE $f_LO.1 && (comm --nocheck-order -3 -1 $f_RE $f_LO) >> $f_LO.1
cp $f_LO $f_LO.2 && (comm --nocheck-order -3 -2 $f_RE $f_LO) >> $f_LO.2
(comm --nocheck-order -1 -2 $f_LO $f_RE) > $f_LO.3
(comm --nocheck-order -3 -1 $f_RE $f_LO) >> $f_LO.3
(comm --nocheck-order -3 -2 $f_RE $f_LO) >> $f_LO.3
counts_1="$(wc $f_LO.1 | awk '{ print $1,$2,$3 }')"
counts_2="$(wc $f_LO.2 | awk '{ print $1,$2,$3 }')"
counts_3="$(wc $f_LO.3 | awk '{ print $1,$2,$3 }')"
# same counts, Ok
if [ $counts_1 = $counts_2 ] && [ $counts_2 = $counts_3 ]; then
cd $remote_path
bash -c "$(comm --nocheck-order -3 -1 $f_RE $f_LO)"
cd $local_path
bash -c "$(comm --nocheck-order -3 -2 $f_RE $f_LO)"
cp $f_LO.3 $f_RE
mv $f_LO.3 --force $f_LO
rm $f_LO.1 $f_LO.2
else
echo "========= manual intervention might be needed ==========="
echo "Results of analysis of $f_LO & $f_RE via [comm] app has not matched;"
echo "renaming/moving not performed;"
echo "rsync of $local_path & $remote_path not performed; see differences between files:"
echo "$f_LO.1, $f_LO.2, $f_LO.3"
echo "========================================================="
to_rsync=0
fi
fi
# if only local exists
elif [ -f $f_LO ]; then
cd $remote_path && $f_LO
fi
# ===== end of workaround ===== #
if [ $to_rsync -eq 1 ];then
rsync $options $local_path/ $remote_path
rsync $options $remote_path/ $local_path
rsync $options $local_path/ $remote_path
fi
# below is to move old versions away
find "$local_path" -path "$local_path/prevs" -prune -o -name '*.bak' -exec mv "{}" "$local_path/prevs" \;
find "$remote_path" -path "$remote_path/prevs" -prune -o -name '*.bak' -exec mv "{}" "$remote_path/prevs" \;
# previous versions, prune works "more correct", forgot why
# find $local_path -maxdepth 1 -name '*.bak' -exec mv "{}" $local_path/prevs \;
# find $remote_path -maxdepth 1 -name '*.bak' -exec mv "{}" $remote_path/prevs \;
else
echo $remote_path is not available
fi
}
# trailing / would prevent proper pruning in find commands
local_path=/home/$(id -un)/Documents
remote_path=/media/$(id -un)/Projects
do_sync
正解はhttps://serverfault.com/questions/489289/handling-renamed-files-or-directories-in-rsync私が理解したことにはいくつかの欠点があります。
ハードリンクの使用:ほとんどのシステムはディレクトリへのハードリンクをサポートしておらず、どちらの名前が変更されたかを確認しません(バックアップは可能ですが同期はできません)。
stat filename
ファイルのどちらの名前が変更されたかを確認するために使用できますが、rsyncとマージする方法がわかりません。