web-dev-qa-db-ja.com

ディレクトリを一方向同期しますが、削除されたファイルは宛先で削除されたままにします

2つのシステム間でディレクトリを同期したい。より面白くするために、同期は一方向でのみ行う必要があります。

  • ファイルがソースディレクトリで削除された場合、以前に転送されていた場合、宛先でも削除する必要があります。
  • 宛先ディレクトリで削除されたファイルは、ソースで削除してはなりません
  • 部分的に転送されたファイル(ネットワークの問題など)は、次の同期で終了する必要があります
  • ソースディレクトリ内の新しいファイルを宛先に転送する必要があります
  • 宛先ディレクトリで削除されたファイルは再転送しないでください

つまり、ソースシステムには基本的にマスターの役割がありますが、宛先で削除されたファイルは強制的に戻されません。

どちらのLinuxシステムでも、rsync/ssh/scpを使用できます。

ソースディレクトリ内の新しいファイルは、mtimeを使用してそれらを検出できるように作成されます。例:

if mtime(file) > date-of-last-sync then: it is a new file that needs to be transfered

また、既存のファイルはソースディレクトリで変更されません。つまり、同期は、すでに(完全に)転送されたファイルの違いを確認する必要はありません。

6
maxschlepzig

転送されたもののデータソースとしてリモートファイルシステムを使用しない場合は、以前に正常に転送されたファイルを外部で追跡し、今後の転送から除外する必要があります。

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を解析することで、おそらく同じ結果を得ることができます。

2
Matt