2つのシステム間でディレクトリを同期したい。より面白くするために、同期は一方向でのみ行う必要があります。
つまり、ソースシステムには基本的にマスターの役割がありますが、宛先で削除されたファイルは強制的に戻されません。
どちらのLinuxシステムでも、rsync/ssh/scpを使用できます。
ソースディレクトリ内の新しいファイルは、mtimeを使用してそれらを検出できるように作成されます。例:
if mtime(file) > date-of-last-sync then: it is a new file that needs to be transfered
また、既存のファイルはソースディレクトリで変更されません。つまり、同期は、すでに(完全に)転送されたファイルの違いを確認する必要はありません。
転送されたもののデータソースとしてリモートファイルシステムを使用しない場合は、以前に正常に転送されたファイルを外部で追跡し、今後の転送から除外する必要があります。
rsync
は、patternsに基づいてファイルをファイルに含めたり除外したりできるため、特定のリストを含めることができます転送中のファイル。次に、そのリストを将来の転送から除外します。
#!/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
固有の正規表現を引用する必要があるかもしれませんが、Perl quotemeta
関数と置換が最初に思いついた簡単な解決策でした。
主な問題は、ファイル名の特殊文字を処理することです。名前の新しい行やタブ、その他の奇妙なことに対処したい場合は、包含パターンリストを解析して生成するPerl
(またはその他)にもう少し作業を加える必要があります。転送ファイルの名前を単純な文字セットに制限できる場合は、この手順についてそれほど心配する必要はありません。 Perl
は、最も一般的な正規表現の文字を通過する必要がある中途半端なソリューションです。
rsync
にディレクトリ全体を自分でプルさせるのではなく、インクルードリストを使用する理由は、後続のエクスクルードリストにファイルの定義済み/完全なリストを提供するためです。転送されたが少し難しく見えたファイルのrsync
出力または--log-file=FILE
を解析することで、おそらく同じ結果を得ることができます。