rsync – исключить все директории и файлы, кроме нескольких

Вопрос или проблема

Я пытаюсь применить метод из https://serverfault.com/a/788007/154366, но он каким-то образом не срабатывает.

Вот моя тестовая настройка:

#!/bin/bash
mkdir -p /tmp/test/{a/b,b/{a,b},c,.d}
touch /tmp/test/{f.txt,.f.txt,{a/b,b,b/{a,b},c,.d}/f.txt,b/.f.txt}
tree -a /tmp/test
/tmp/test
├── a
│   └── b
│       └── f.txt
├── b
│   ├── a
│   │   └── f.txt
│   ├── b
│   │   └── f.txt
│   ├── .f.txt
│   └── f.txt
├── c
│   └── f.txt
├── .d
│   └── f.txt
├── .f.txt
└── f.txt

Из /tmp/test я хотел бы скопировать с помощью rsync -a полную директорию ./a, полную директорию ./b/b, файлы и скрытые файлы, находящиеся на первом уровне в ./b, а также файлы (не скрытые) на первом уровне в ./.

Ожидаемые “копии” (обозначенные ->) будут:

/tmp/test/           ->  /tmp/filt/
/tmp/test/a/         ->  /tmp/filt/a/
/tmp/test/a/b/       ->  /tmp/filt/a/b/
/tmp/test/a/b/f.txt  ->  /tmp/filt/a/b/f.txt
/tmp/test/b/         ->  /tmp/filt/b/
/tmp/test/b/a/
/tmp/test/b/a/f.txt
/tmp/test/b/b/       ->  /tmp/filt/b/b/
/tmp/test/b/b/f.txt  ->  /tmp/filt/b/b/f.txt
/tmp/test/b/f.txt    ->  /tmp/filt/b/f.txt
/tmp/test/b/.f.txt   ->  /tmp/filt/b/.f.txt
/tmp/test/c/
/tmp/test/c/f.txt
/tmp/test/.d/
/tmp/test/.d/f.txt
/tmp/test/f.txt      ->  /tmp/filt/f.txt
/tmp/test/.f.txt

Поэтому я создал файл filter.txt для rsync:

+ /[!.]*
+ /a/
+ /a/**
+ /b/
+ /b/b/
+ /b/b/**
- /b/*/
+ /b/*
- /**

Но когда я пытаюсь это сделать:

rsync -av --dry-run --filter="merge filter.txt" /tmp/test /tmp/filt/

Я получаю:

sending incremental file list
test/

sent 74 bytes  received 20 bytes  188.00 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)

примечание: ls /tmp/filt выводит ошибку ls: cannot access /tmp/filt: No such file or directory

Что не так?

Ответ или решение

Использование rsync для копирования отдельных директорий и файлов

При использовании rsync для копирования файлов и директорий может возникнуть необходимость исключить все, кроме нескольких специфичных каталогов и файлов. Давайте рассмотрим, как это адаптировать для вашей ситуации.

Проблемное Обозначение

У вас есть набор файлов и директорий в /tmp/test, и вы хотите скопировать только определённые элементы в директорию /tmp/filt/. Ваша цель состоит в том, чтобы включить следующие элементы:

  1. Полный каталог ./a и все его содержимое.
  2. Полный каталог ./b/b и все его содержимое.
  3. Файлы и скрытые файлы (dotfiles) в каталоге ./b.
  4. Файлы (не скрытые) в корневом каталоге ./.

Если рассмотреть текущую реализацию через файл фильтрации filter.txt, то нужно сделать несколько изменений, чтобы rsync работал должным образом.

Файл filter.txt

Ваш файл filter.txt имеет хорошую структуру, но требует нескольких корректировок для правильной работы. Вот исправленная версия:

+ /a/
+ /a/**
+ /b/
+ /b/b/
+ /b/b/**
+ /b/.*
+ /b/*
- /b/*/
- /**

Объяснение фильтров:

  1. + /a/ – включает полный каталог a.
  2. + /a/** – включает все содержимое внутри каталога a.
  3. + /b/ – включает каталог b.
  4. + /b/b/ – включает каталог b/b.
  5. + /b/b/** – включает все внутри каталога b/b.
  6. + /b/.* – включает все скрытые файлы в каталоге b.
  7. + /b/* – включает все обычные файлы в каталоге b.
  8. - /b/*/ – исключает все подкаталоги в каталоге b.
  9. - /** – исключает все остальное содержимое.

Использование rsync

Теперь, чтобы выполнить вашу задачу, можете использовать следующую команду rsync:

rsync -av --dry-run --filter="merge /path/to/filter.txt" /tmp/test/ /tmp/filt/

Разбор команды

  • -a – это архивный режим, который сохраняет права и временные метки.
  • -v – включает подробный режим, что помогает увидеть, какие файлы передаются.
  • --dry-run – позволяет протестировать команду без фактического выполнения операции, что полезно для проверки корректности настроек.
  • --filter – указывает на файл с фильтрами, которые будут применены при копировании.

Итоги

После внесения корректировок в файл фильтрации и правильного использования команды rsync вы сможете достичь желаемого результата. Применяя вышеуказанные указания, вы сможете скопировать только те файлы и каталоги, которые вам нужны, при этом исключив все остальные.

Если после выполнения команды rsync с изменённым фильтром все ещё возникают вопросы, не стесняйтесь задавать их для получения дополнительной информации и помощи.

Оцените материал
Добавить комментарий

Капча загружается...