rsyncを使用して循環スキームを実装する方法

rsyncを使用して循環スキームを実装する方法

rsync私はいつも私のターゲットディレクトリに最新のN個のファイルだけを保持することを目指して(つまり、ある程度循環スキーム)以前にソートしてフィルタリングしたいリモートファイルディレクトリがますます増えています。rsyncこれにはオプションがないようで、以下のように「任意のリモートコマンド挿入」技術を使用してきました。

https://stackoverflow.com/q/950062/787842

私はターゲットホストでcronとして実行する次のコマンドを思いつきました。

rsync -vrzO --delete \
    -e ssh <remote_host>:'$(cd <remote_dir> && ls -t $PWD/* | head -n 25)' \
    <destination_dir>

これは最初はうまく機能します(つまり、ターゲットディレクトリが空の場合)。最新の25ファイルのみがコピーされます。ただし、問題は、ウィンドウが「前方にスライドする」(つまり、新しいファイルが到着したときに古いファイルをローカルでプッシュする必要がある場合)、期待--deleteどおりにこのオプションが機能しないことです。私の考えでは、フィルタリングされたリモートファイルがまだ存在するため(つまり、'$(..)'挿入されたコマンドによって一時的に隠されただけなので)、rsyncローカルでフィルタリングする方法はありません。私の理解が正確でより良い方法はありますか?

答え1

次のようにコマンドをシミュレートできます。

rsync -vrzO --delete -e ssh <remote_host>:'<remote_dir>/file1 <remote_dir>/file2' <destination_dir>/ これが置き換えられた出力ですcd <remote_dir> && ls -t $PWD/* | head -n 2

rsyncは--deleteディレクトリですコマンドの置き換えファイルリストを提供します。だから--delete動作しません。

抜粋man rsync:

- 削除

これはrsyncに、受信側から不要なファイル(送信側にないファイル)を削除するように指示します。ただし、ディレクトリのみ 同期中です。あなた 完全なディレクトリを送信するには、rsyncに要求する必要があります。ディレクトリの内容( "dir / *"など)にワイルドカードを使用する代わりに( "dir"または "dir /"など)、ワイルドカードはシェルによって拡張されるため、rsyncは要求ではなく単一のファイル転送要求を受け取ります。ファイルの親ディレクトリについて。

答え2

リモートディレクトリを次にマウントします。sshfs。その後、それをローカルディレクトリとして処理できます。

これで、修正時間でファイルをソートする最も簡単な方法は次のとおりです。扱いにくい~のグローバル予選。ディレクトリ内の最新の25ファイルは次のとおりです。

*(NDom[1,25])

したがって、最初にコピーするには、ターゲットから関連のないファイルを削除してください。

for x in source/*(NDom[1,25]); do
  y=destination/${x:t}
  if [[ ! -e $y || $x -nt $y ]]; then cp -p $x $y; fi
done
destination_files=(destination/*(NDom[1,25]))
if [[ ${#destination_files} -gt 25 ]]; then
  shift $((${#destination_files} - 25)) destination_files
  rm $destination_files
fi

これは、ファイルをコピーする前に削除する別の方法です。新しいファイルをコピーする必要があり、ターゲットにすでに完全なファイルがある場合、このファイルは最も古いファイルを削除します。

destination_files=(destination/*(ND)); destination_count=$#destination_files
for x in source/*(NDom[1,25]); do
  y=destination/${x:t}
  if [[ $destination_count -gt 25 && ! -e $y ]]; then rm destination/*(NDom[-1]); fi
  if [[ ! -e $y || $x -nt $y ]]; then cp -p $x $y; fi
done

(警告:上記のコードはブラウザに直接入力したのでテストしませんでした。)

関連情報