rsync、送信側で削除された受信側のファイルを削除します。(しかし、すべてを削除しないでください)


9

rsyncを使用して...

  • 送信側でも削除された受信側のファイルを削除する
  • 受信側のrsyncedディレクトリにある他のファイルを削除しない

たとえば、私がディレクトリを持っているとしましょうlocal-src

変更前: local-srcローカルに含まれる...

a.txt
b.txt
c.txt

toのコンテンツに同期したいリモートディレクトリlocal-srcはという名前remote-srcです。

変更前: remote-srcリモートで含む...

a.txt
b.txt
c.txt
d.txt
README.md

私がいくつかのファイルを削除したとしましょうlocal-src

ローカル削除後: local-srcローカルに含む...

c.txt

ソースで削除されたファイルが宛先でも削除されるように、ただし宛先で他のファイルを削除せずに、rsyncをどのように使用できますか?たとえば、宛先で次のようにしたいとします。

ローカル削除後: remote-srcリモートに含む...

c.txt
d.txt
README.md

つまり、a.txtおよびb.txtリモートからも削除されますが、d.txtREADME.txt放置されています。

rsyncでこれを達成する方法はありますか?

編集:評決はこれがrsyncでは不可能かもしれないということであるようです。これが必要な理由を尋ねられたので、私のユースケースを説明します。

Webサーバーがあるとします。そのWebサーバーには、多数のディレクトリがあります。たとえば、ディレクトリApublic_htmlサイトの提供元のディレクトリがあるとします。ディレクトリにファイルを作成する自動化されたプロセスがあるとしますA。内にある可能性のある他の任意のファイルを削除せずに、ディレクトリに生成または更新されたファイルをrsync(または他のツールを使用して同期)したい。rsyncが誤って自分のウェブサイトを削除して欲しくないのは確かです。Apublic_htmlpublic_html

rsyncがこのジョブのツールではない場合、他の誰かが私がこれを行う方法を知っていますか?


2
あなたの質問をもう一度読んだ後、rsyncどのファイルがすでにリモートフォルダにあるのかを知る方法がないので、これは可能ではないと思います。別のツールを見つける必要があるかもしれません。
Spack 2013年

rsyncはこれを許可しませんが、ファイルを削除するたびにディレクトリ全体をscpする場合、それらは同期を保つことができ、単なる解決策ではありません。
アーディドロイド2013

1
あなたはすでにこれについて考えていると思いますが、これらのファイルをサブディレクトリ(または他の場所)に配置して、public_htmlから参照することはできませんか?これにより、ウェブサーバーのファイルシステムの他の部分にあるファイルに影響を与えることなく、簡単かつ明示的に同期される1つのディレクトリを作成できます。
MattJenko、2014年

回答:


2

あなたがしたいことは合理的ですが、それをrsync単独で行うために使うことは妥当ではありません。だから答えはノーです。

理由は単純です。rsync各ディレクトリに何があったかについての履歴を保持せず、何を削除する必要があるか、何を削除する必要があるかを知る方法がありません。追加のサポートなしではありません。

なぜこれを行うのが好きかを自問しrsync、それをより明確にする必要があります。librsync1.soよりインテリジェントな使用する他のプログラムがあります。


rsyncそれ自体 必要のない緩和された制約により、rdiff-backupを確認できます。

mkdir a
touch a/xx
touch a/yy
rdiff-backup a b
ls b 

これはショーxxyyですb

touch b/zz
rm a/xx
rdiff-backup a b

これはショーxxzzですbrdiff-backupまた、変更をロールバックできるようにディレクトリrdiff-backup-dataを保持brdiff-backupます。コマンドを使用して定期的に削除する必要があります。(この例では、ターゲットの追加データが削除されないことを示すローカルファイルを使用していますが、rdiff-backupもネットワーク経由で機能します)。


別の方法は、分散リビジョン管理システム(mercurial、bazaar、git)をセットアップすることです。mercurialを使用すると、スクリプト(私はMakefileを使用します)を作成できます。このスクリプトは、すべての変更をサーバーにプッシュしてから、チェックアウトされたファイルの更新を行い、リモートサーバーにある追加ファイルを無視します(ただし、リビジョン管理下に置かれていません)。

サーバーでは次のようにします。

hg init
hg add file_list_excluding_that_should_not_should_be_deleted_if_not_on_client
hg commit -m "initial setup"

クライアント上:

hg clone ssh://username@server/dir_to_repository

ここで、クライアント上のファイルを削除して次のようにした場合:

hg commit -m "removed file"
ssh username@server "cd dir_to_repository; hg update --clean"

削除されたファイルはサーバーから削除されますが、その他のデータ(リポジトリに追加されていない)は削除されません。


rsyncがこれを行わないことを受け入れます。しかし、これがrsyncでは不可能であることには同意しません。rsyncが送信側で削除されたファイルを知っている場合、その情報をdiffで受信側に送信できないのはなぜですか?鮮度を比較した後、diffで削除するように指示されたファイルを受信側が削除できず、ディレクトリ内の他のすべてを削除できない理由がわかりません。ディレクトリ内の他のすべての(ソースで削除されていない)無害なファイルを削除することは、私には無理のようです。
Heather Miller

とにかく、これが必要な理由は次のとおりです。私はディレクトリを持っています、それを呼び出しましょうA。そこでは、いくつかのプロセスが自動化されており、ファイルはそこで自動的に生成されます。私はWebサーバーを持っています。もちろん、Webサーバーのフォルダー内の他のすべてを削除せずに、その中のファイルをWebサーバーApublic_htmlディレクトリにrsyncしたいと思いpublic_htmlます。別のツールでこれを達成するためのアイデアがあれば、それは大歓迎です。これを反映するように質問を更新します。
Heather Miller

上記の私の最初のコメントを明確にするために、「rsyncのようなツールでは、このようなことは不可能であるべきだということに同意しません」と言ったはずです。直感的に、これは達成するのが難しいことではないようです(私が何かを逃していない限り)。
Heather Miller

うーん、OK。私は今見ていると思います- local-srcそのディレクトリの変更を監視しているプロセスがなくても、ディレクトリで何かが削除されたときにrsyncがそれを知る方法 多分これは難しいでしょう。
Heather Miller

@HeatherMiller私が書いたように、あなたのリクエストは合理的ですがrsync、ツールではありません。syncin rsyncは同期から発生するものであり、それがまさにあなたがやりたいことではないことを理解してください。開発のrsync焦点は、データ転送の効率化(最小化)でした。他のrdiff-backup(および可能性のあるcvsup)ツールは、そのための手法を使用していますが、追加の機能を使用してその上に構築されています。
アントーン2013年

1

これは、rsyncコマンドの一部として受信側のファイルを明示的に除外しないと可能ではないと思います。rsyncのmanページのセクションを参照してください:「ディレクトリごとのルールと削除」。

削除オプションがない場合、ディレクトリごとのルールは送信側にのみ関係するため、転送に影響を与えずにマージファイル自体を自由に除外できます。これを簡単にするために、次の2つの同等のコマンドに見られるように、 'e'修飾子はこの除外を追加します。

          rsync -av --filter=': .excl' --exclude=.excl host:src/dir /dest
          rsync -av --filter=':e .excl' host:src/dir /dest

ただし、受信側で削除を行い、一部のファイルを削除から除外したい場合は、受信側が除外するファイルを認識していることを確認する必要があります。最も簡単な方法は、ディレクトリごとのマージファイルを転送に含めて--delete-afterを使用することです。これにより、受信側が何かを削除しようとする前に、送信側と同じ除外ルールがすべて取得されることが保証されます。

          rsync -avF --delete-after host:src/dir /dest

ただし、マージファイルが転送の一部ではない場合は、いくつかのグローバル除外ルール(つまり、コマンドラインで指定)を指定するか、独自のディレクトリごとのマージファイルを受信側。最初の例は次のとおりです(リモートの.rulesファイルがそれ自体を除外するとします):

   rsync -av --filter=’: .rules’ --filter=’. /my/extra.rules’
      --delete host:src/dir /dest

上記の例では、extra.rulesファイルは転送の両側に影響を与える可能性がありますが、(送信側で)ルールは、ディレクトリごとのマージルールの後に指定されているため、.rulesファイルからマージされたルールに従属します。

最後の1つの例では、リモート側で.rsync-filterファイルを転送から除外していますが、独自の.rsync-filterファイルを使用して、受信側で何を削除するかを制御します。これを行うには、ディレクトリごとのマージファイルを明確に除外し(ファイルが削除されないようにするため)、ローカルファイルにルールを追加して、他に削除してはならないものを制御する必要があります。これらのコマンドの1つと同様に:

       rsync -av --filter=':e /.rsync-filter' --delete \
           host:src/dir /dest
       rsync -avFF --delete host:src/dir /dest

0

私が正しく理解していれば、--excludeあなたが探しているものかもしれません:

$ ls src dst
dst:
a.txt  b.txt  c.txt  d.txt  README.md

src:
c.txt
$ rsync --update --delete --recursive --exclude="d.txt" --exclude="README.md" src/ dst
$ ls src dst
dst:
c.txt  d.txt  README.md

src:
c.txt

うーん、ダメ。除外するすべてのファイルを手動でリストする必要はありません。ソースで削除したファイルのみをrsyncで削除したいのですが、宛先で同じディレクトリに存在する可能性のある他のファイルがソースにある必要はありません。
Heather Miller

0

それに対する答えがあります。うまくいくと思います。そして、それは私のために働きます。まず、rsyncリモートファイルからローカルファイルに移動する必要があります。次に、ローカル側にすべてのファイルが含まれます。

sudo rsync -r -a -v --delete /root@xx.xx.xx.xx:/remote_dir/ /local_dir/

今ローカル側に

a.txt
b.txt
c.txt
d.txt
README.md

次に、ファイルを削除するか、必要な操作を実行できます(ローカル側で)。あなたの質問では、これらのファイルを削除します。

削除されたファイル

a.txt
b.txt

その後rsync、リモート側にファイルをローカル化できます。その後、両方の側に同じファイルがあります。

sudo rsync -r -a -v --delete /local_dir/ root@xx.xx.xx.xx:/remote_dir/

それは与えます

c.txt
d.txt
README.md

リモート側とローカル側--deleteのファイル(を使用して、ローカル側と一致しないリモート側の他のファイルを削除します)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.