rsync исключить каталог не работает

34

Я использую Fedora 17 64-bit и rsync --exclude=/home/ben/<dir>не работает должным образом.

Я пытаюсь переместить rsyncмой домашний каталог на флэш-накопитель, но я хочу, конечно, исключить каталоги, в которых хранятся файлы кэша и файлы сборки. Это команда, которую я использую:

rsync --exclude=/home/ben/build/ --exclude=/home/ben/.ccache -arv /home/ben home-ben/

Тем не менее, содержимое из ~/buildи ~/.ccacheкопируется rsync. Что я делаю не так?

Freedom_Ben
источник
1
Я думаю, что исключить шаблоны просто не работают.
Сёрен

Ответы:

37

rsyncПравила глобального фильтра, начинающиеся с ведущего /, привязаны к корню передачи. Цитата из раздела «ВКЛЮЧИТЬ / ИСКЛЮЧИТЬ ПРАВИЛА ШАБЛОНА» справочной страницы:

если шаблон начинается с /, то он привязывается к определенной точке в иерархии файлов, в противном случае он сопоставляется с концом пути. Это похоже на ведущий ^ в регулярных выражениях. Таким образом, «/ foo» будет соответствовать имени «foo» либо в «корне передачи» (для глобального правила), либо в каталоге файла слияния (для правила для каждого каталога).

По вашей команде ( rsync ... -arv /home/ben home-ben/) файл /home/ben/fooбудет передан home-ben/ben/foo. Корень передачи home-benи правильный путь фильтра /ben/foo. Таким образом,

  • чтобы соответствовать /home/ben/.ccacheвам нужен путь фильтра/ben/.ccache
  • чтобы соответствовать /home/ben/build/вам нужен путь фильтра/ben/build/

Более подробное объяснение можно найти в разделе «ЯКОРЬ ВКЛЮЧИТЬ / ИСКЛЮЧИТЬ РИСУНКИ» rsync(1)страницы руководства .


Обратите внимание, что просто опустить ведущие /не обязательно то, что вы хотите. Цитируем снова из того же раздела справочной страницы:

Неквалифицированный «foo» будет соответствовать имени «foo» в любом месте дерева, потому что алгоритм применяется рекурсивно сверху вниз; он ведет себя так, как будто каждый компонент пути получает поворот в конце имени файла. Даже незанятый «sub / foo» будет совпадать в любой точке иерархии, где «foo» найден в каталоге с именем «sub». См. Раздел «ЗАКЛЮЧЕНИЕ ВКЛЮЧАЙТЕ / ИСКЛЮЧАЙТЕ ШАБЛОНЫ» для полного обсуждения того, как указать шаблон, который совпадает с корнем передачи.

Таким образом, шаблон фильтра build/будет соответствовать каталогу сборки в любом месте /home/ben, даже /home/ben/many/sub/directories/build/.

jw013
источник
2
Ключевая деталь - это то, что разрезает материю. Если вы добавите косую черту в конец исходного каталога (rsync -a source / destination), он скопирует содержимое исходного кода, в противном случае rsync -a source destinationсам исходный каталог будет скопирован в место назначения. Это определяет, каким будет корень передачи для информирования выражения исключения. Правильное использование / в выражении исключения объясняется выше. Обратите внимание, в частности, что rsync --exclude='/dir1' source destinationничего не исключает.
pgoetz
11

Я думаю, что ваши excludeпути должны быть относительно исходного пути. Можете ли вы попробовать это вместо этого?

rsync --exclude=build/ --exclude=.ccache -arv /home/ben home-ben/

Вот тест для сравнения:

/tmp$ tree src dest
src
├── a
└── b
dest
└── foo/

/tmp$ rsync -nav --exclude /tmp/src/b /tmp/src /tmp/dest
sending incremental file list
src/
src/a
src/b

$ rsync -nav --exclude b /tmp/src /tmp/dest
sending incremental file list
src/
src/a
HorsePunchKid
источник
2
Этот ответ неверен. С относительным путем исключения вы бы исключили шаблон везде!
rubo77
Этот пост правильный. Соответствие основано на тексте, а не на файловом индексе. Какой бы путь не выводил вывод --verboseкоманды, это формат, который вы должны использовать.
Шридхар Сарнобат
Это сработало для меня.
Женю
Что, если исходный путь равен '/', тогда абсолютными являются относительные пути, но он все равно не работает.
Сёрен
Это единственное, что сработало для меня.
Джонатан
2

У меня была эта проблема в сценарии (я не знаю, если это ваш случай). Я был, потому что я использовал эту команду в сценарии, и я использовал sh вместо bash. проверьте Шебанг в начале вашего сценария.

Джауед Захрауи
источник
1

Ваш шаблон исключения будет работать, если вы rsync весь путь / home, то есть без завершающей косой черты:

rsync --exclude=/home/ben/build/ --exclude=/home/ben/.ccache -arv /home home-all/

Но лучше только rsync содержимое папки с косой чертой:

rsync --exclude=/build --exclude=/.ccache -arv /home/ben/ home-ben/

Вы также можете использовать список игнорирования, см .: https://askubuntu.com/questions/545655/backup-your-home-directory-with-rsync-and-skip-useless-folders

rubo77
источник
0

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

rsync --exclude=/ben/build/ --exclude=/ben/.ccache -arv /home/ben home-ben/

где «ben» - папка, которую вы синхронизируете

Самохт Рускони
источник