web-dev-qa-db-ja.com

Rsyncフィルターを使用してファイルを含めたり除外したりする

ファイルシステムをバックアップしようとしていますが、/mntを除外しますが、/mnt内に特定のパスを含めます。--includeおよび--excludeよりも--filterを使用することをお勧めしますが、しません。私の入札を行うためにそれを得ることができるようです、例:

rsync -aA -H --numeric-ids -v --progress --delete \
  --filter="merge /tmp/mergefilter.txt" /  /mnt/data/mybackup/

私の/tmp/mergefilter.txtはこう言っています:

+ /mnt/data/i-want-to-rsyncthisdirectory/
- /dev
- /sys/
- /tmp/
- /run/
- /mnt/
- /proc/
- /media/
- /var/swap
- /lost+found/

「-」で始まるパスはすべて無視されますが、/mnt/data/i-want-to-rsyncthisdirectory/のインクルードがrsync 'dになることはないようです。末尾のスラッシュを順序付けおよび/または含める/除外しても、含めたいパスに関連する動作が変わるようには見えません。

EDIT: Idoは、/として指定されたソースに従って/ etc/usr/varなどをバックアップしたいことに注意してください。

マニュアルページはちょっとした地雷原なので、ガイダンスに感謝します...

6
user5611823

私にとって、このコマンドは仕事をしています:

rsync -aA -H --numeric-ids -v --progress --delete \
--filter="+ /mnt/data/i-want-to-rsyncthisdirectory/" \
--filter="- *" . /mnt/data/mybackup/

基本的に、私は問題のディレクトリに+フィルタを使用し、他のすべてを除外しました(与えられた例で行うように)。

同期したくないすべてのディレクトリを明示的に無効にする必要はありません。代わりに、問題の1つを除くすべてを無視できます。

8
Marcus

この質問はかなり古いですが、これはあなたを助けるかもしれないと思います:

(rsync 3.1.2マニュアルから)

--recursive(-r)オプション(-aで示される)を使用すると、すべてのパスのすべてのサブコンポーネントが上から下にアクセスされるため、包含/除外パターンが各サブコンポーネントのフルネームに再帰的に適用されることに注意してください(例: 「/ foo/bar/baz」を含めるには、サブコンポーネント「/ foo」と「/ foo/bar」を除外しないでください)。除外パターンは、rsyncが送信するファイルを見つけると、実際にはディレクトリトラバーサルステージを短絡させます。パターンが特定の親ディレクトリを除外する場合、rsyncが階層のその除外されたセクションを下っていなかったため、より深いインクルードパターンが無効になる可能性があります。これは、末尾の「*」ルールを使用する場合に特に重要です。たとえば、これは機能しません。

         + /some/path/this-file-will-not-be-found
         + /file-is-included
         - *

親ディレクトリ「some」が「*」ルールによって除外されているため、これは失敗します。そのため、rsyncは「some」または「some/path」ディレクトリ内のファイルにアクセスすることはありません。 1つの解決策は、「+ * /」(「-*」ルールの前のどこかに置く)という単一のルールを使用して、階層内のすべてのディレクトリを含めるように要求し、おそらく--Prune-empty-dirsオプションを使用することです。 。もう1つの解決策は、訪問する必要のあるすべての親ディレクトリに特定のインクルードルールを追加することです。たとえば、この一連のルールは正常に機能します。

         + /some/
         + /some/path/
         + /some/path/this-file-is-found
         + /file-also-included
         - *

私は元の回答で実際には機能しないものを提案しました(私はそれをテストしました)。私はあなたと同じような木を再現し、この解決策は今うまくいくはずです:

+ /mnt/
+ /mnt/data/
+ /mnt/data/i-want-to-rsyncthisdirectory/
- /mnt/data/*
- /mnt/*
- /dev
- /sys/
- /tmp/
- /run/
- /proc/
- /media/
- /var/swap
- /lost+found/

説明:

(最後にマニュアルを言い換えるだけですが、あなたが言ったように、マニュアルは少し不可解です)

Rsyncでファイルを転送する必要があるたびに、ルールが上から下に読み取られます。ただし、あなたの場合/ mnt/data/i-want-to-rsyncthisdirectory /は除外するため、バックアップされません/ mntこれにより、インクルードルールが短絡します。したがって、解決策は、バックアップするフォルダーまで各フォルダーとサブフォルダーを含めてから、サブフォルダーごとにサブフォルダーをバックアップしたくないものを除外することです。

各サブフォルダーの除外の最後にある*に注意してください。それはrsyncがこれらのサブフォルダーにあるファイルとフォルダーをバックアップするのを防ぎます。これはあなたが望むものです。

より簡単な解決策:(編集2)

バージョン2.6.7で追加された**​​パターンを使用して、これを単純化することもできます。

+ /mnt/
+ /mnt/data/
+ /mnt/data/i-want-to-rsyncthisdirectory/***
- /mnt/**

この演算子を使用すると、除外に**​​ワイルドカードを使用できるため、除外行を1つだけにすることができます。

また、次のrsync引数のおかげで、どのフィルタールールが各ファイルまたはフォルダーを除外/含めるかを理解できることも発見しました。

--verbose --verbose

-dry-run引数と組み合わせると、問題をデバッグできるはずです:)

7
Tom

私のように他の誰かがこれと戦っている場合に備えて、私は何とか以下を機能させることができました。私の場合、別のサーバーからリポジトリを選択的に同期しています。

ファイルにフィルターを配置します。

+ epel/
+ epel/7/
+ epel/7/x86_64/
+ epel/7/x86_64/Packages**
+ epel/7/x86_64/repodata**
- **

そして、意図したとおりにすべてを同期できます。

cd /srv/repo
rsync -rvzP -f 'merge /home/user/sync-filter.txt' ./ user@remote:/srv/repo/

最初に、フィルターファイルをepel/7/x86_64/Packages/**で設定しましたが、**の前にスラッシュが付いているため、機能しませんでした。 /を削除すると、意図したとおりにすべてが活気づきます。

0
shearn89