2つのシステム間でディレクトリを同期したいと思います。より興味深くするために、同期は一方向にのみ実行できます。つまり:
- ソースディレクトリからファイルを削除した場合は、以前に送信されたファイルもターゲットディレクトリから削除する必要があります。
- ターゲットディレクトリから削除されたファイルは、ソースディレクトリから削除しないでください。
- 部分的に転送されたファイル(ネットワークの問題など)は、次の同期時に完了する必要があります。
- ソースディレクトリの新しいファイルをターゲットディレクトリに転送する必要があります。
- ターゲットディレクトリから削除されたファイルは再送信されない可能性があります。
つまり、ソースシステムはデフォルトでマスターの役割を持ちますが、ターゲットシステムから削除されたファイルは強制的に回復されません。
どちらのLinuxシステムでもrsync / ssh / scpを使用できます。
ソースディレクトリの新しいファイルは、mtimeを使用して検出できる方法で作成されます。例:
if mtime(file) > date-of-last-sync then: it is a new file that needs to be transfered
また、ソースディレクトリの既存のファイルは変更されません。つまり、同期時にすでに(完全に)転送されたファイルの違いを確認する必要はありません。
ベストアンサー1
リモートファイルシステムを転送されたコンテンツのデータソースとして使用する予定がない場合は、以前に正常に転送されたファイルを外部で追跡し、将来の転送から除外する必要があります。
rsync
以下に基づいてファイルを含めるか除外できます。模様転送時に特定のファイルのリストを含めるようにファイルに保存します。これにより、このリストは将来の転送から除外されます。
#!/usr/bin/env bash
set -e
track_dir=~/.track_xfer
inc_file="$track_dir/include_files"
exc_file="$track_dir/exclude_files"
xfer_dir=~/testrsync
xfer_dest=~/testrsync_dest
mkdir -p "$track_dir"
touch $exc_file
cd "$xfer_dir"
# find files and create rsync filter list
find . -type f -print0 | perl -e '
$/="\0";
while (<>){
chomp;
$_ =~ s!^\.!!; # remove leading .
$f = quotemeta; # quote special chars
$f =~ s!\\/!/!g; # fix quoted paths `/`
print $f."\n";
}' > "$inc_file"
# Run the rsync
rsync -va --delete --exclude-from "$exc_file" --include-from "$inc_file" "$xfer_dir/" "$xfer_dest"
# Add the included/transferred files to the exclusion list
cat "$inc_file" "$exc_file" > "$exc_file".tmp
sort "$exc_file".tmp | uniq > "$exc_file"
より具体的な正規表現参照が必要かもしれませんが、rsync
Perlquotemeta
機能と交換が私の心に浮かぶ最初の簡単な解決策です。
主な問題は、ファイル名の特殊文字を処理することです。名前の新しい行、タブ、その他の奇妙な項目を処理するには、perl
パターンリストを含む(または何でも)解析して作成するためにさらに多くの作業を行う必要があります。転送されるファイルの名前を単純な文字セットに制限できる場合は、この手順を心配する必要はありません。perl
最も一般的な正規表現文字を克服するのに役立つトレードオフソリューションは次のとおりです。
rsync
ディレクトリ全体を独自にインポートするのではなく、インクルードリストを使用する理由は、後続の除外リスト用に定義された/完全なファイルリストを持つことです。転送されたファイルrsync
や出力を解析して--log-file=FILE
同じ結果を得ることもできますが、少し難しいようです。