Вопрос или проблема
Я использую Pelican для написания своего блога и загружаю все с помощью rsync
. ОК.
Но я также использую Let’s Encrypt и поэтому мне нужно, чтобы репозиторий .well-known сохранялся в корне моего веб-сайта.
Так есть ли способ сказать “rsync ... --do-not-delete .well-known ...
“.
В настоящее время эти репозитории защищены правами доступа, но rsync это не любит.
Вот текущая команда rsync
(установленная самим Pelican, я ее не писал):
rsync -e "ssh -p $(SSH_PORT)" -P -rvzc --delete $(OUTPUTDIR)/ $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR) --cvs-exclude
Кстати: если у вас есть какие-либо предложения по улучшению эффективности rsync, я воспринимаю это (да, это не по теме).
Из man rsync
–delete
Это говорит rsync удалить лишние файлы на стороне получения
(те, которых нет на стороне отправки), но только для
каталогов, которые синхронизируются. Вы должны были попросить
rsync отправить весь каталог (например, “dir” или “dir/”)
без использования подстановочного знака для содержимого каталога (например, “dir/*”),
поскольку подстановочный знак расширяется оболочкой, и rsync таким образом получает
запрос на передачу отдельных файлов, а не родительского
каталога файлов. Файлы, которые исключены из переноса, также
исключаются из удаления, если вы не используете параметр –delete-excluded
или не отмечаете правила как совпадающие только на стороне отправки
(см. модификаторы include/exclude в разделе ПРАВИЛА ФИЛЬТРА).
Так что я думаю, что это должно быть
rsync -e "ssh -p $(SSH_PORT)" -P -rvzc --delete \
$(OUTPUTDIR)/ \
$(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR) \
--cvs-exclude --exclude=/.well-known
(предполагая, что .well-known
находится в корне $(SSH_TARGET_DIR)/
)
Вы должны использовать параметр --exclude
, чтобы заставить rsync
игнорировать этот каталог. Если вы не используете --delete-excluded
(чего не следует делать в этом случае), он останется нетронутым.
Принятый ответ не работал для меня так хорошо с более сложной синхронизацией, но я обошел это, используя простой фильтр.
Я не хотел помещать специфичные для rsync файлы конфигурации (.rsync-filter
и т.д.) среди тех, которые хотел передать, чтобы обе стороны оставались чистыми.
Отправка:
/path/to/local/sync/root/
├─ sub/
│ ├─ dir/
│ │ ├─ foo/
├─ sub2/
├─ sub3/
Получение:
host:/path/to/remote/sync/root/
├─ sub/
│ ├─ dir/
│ │ ├─ foo/
│ │ ├─ bar/
│ │ ├─ baz/
├─ sub2/
├─ sub3/
Я хотел синхронизировать только некоторые каталоги в корне и сохранить baz/
, но в остальном удалить файлы, отсутствующие на стороне отправки (здесь bar/
).
Решением было создать файл .rules
, который находился вне корней синхронизации, с следующим правилом, которое привязано к корню синхронизации:
exclude /sub/dir/baz
Я всегда проверяю, что будет синхронизировано с помощью --dry-run
:
rsync --dry-run --delete-after --itemize-changes --archive --no-devices --no-specials \
--relative --filter=". /other/path/to/my.rules" \
/path/to/local/sync/root/./sub/dir/ \
/path/to/local/sync/root/./sub3/ \
host:/path/to/remote/sync/root/ \
| LC_COLLATE=C sort --ignore-leading-blanks --key=2 \
| less -niS
Важные части это --delete-after
, чтобы гарантировать, что правила исключения уважаются на стороне получения, и --filter
.
Сортировка по именам файлов делает проверку действий намного проще, так как она показывает удаления среди других изменений, даже если rsync не выполняет операции в этом порядке.
Как только я буду доволен сообщенными изменениями, я убираю пайпы к sort
& less
, убираю --dry-run
и выполняю.
Секреты всегда в мелочах, например “какой каталог мне указать как назначение”. Ответ – это родительская папка.
Например, если у меня есть папка с фруктами с обеих сторон, я должен указать родительскую папку как назначение для работы. Тогда rsync удалит все внутри фруктов, которых нет в источнике:
rsync -avh fruits the_destiny_fruits_parent_dir --delete
Как уже говорили Hai Luong Dong и Celada, фильтр исключения останавливает совпадения имен с шаблоном фильтра от удаления, если вы не используете --delete-excluded
.
Вы можете вместо этого использовать защитный фильтр, который защищает совпадающие имена от удаления, даже если используется --delete-excluded
. Вы делаете это, используя --filter="protect {PATTERN}"
или -f 'P {PATTERN}'
.
Пример: Синхронизируйте каталог a
с уже существующим каталогом b
, исключая file-2
(будет удален из b
из-за --delete-excluded
) и защищая keep-me
. Файл delete-me
будет удален, так как он отсутствует в a
(из-за --delete
).
$ tree
.
|-- a
| |-- file-1
| |-- file-2
| |-- file-3
| `-- file-4
`-- b
|-- delete-me
|-- file-1
|-- file-2
|-- file-3
|-- file-4
`-- keep-me
3 директории, 10 файлов
$ rsync -avv --filter="protect keep-me" --exclude=file-2 --delete --delete-excluded a/ b
sending incremental file list
[sender] hiding file file-2 because of pattern file-2
delta-transmission disabled for local transfer or --whole-file
[generator] protecting file keep-me because of pattern keep-me
deleting file-2
deleting delete-me
file-1 is uptodate
file-3 is uptodate
file-4 is uptodate
./
total: matches=0 hash_hits=0 false_alarms=0 data=0
sent 115 bytes received 250 bytes 730.00 bytes/sec
total size is 0 speedup is 0.00
$ tree b
b
|-- file-1
|-- file-3
|-- file-4
`-- keep-me
1 директория, 4 файла
Ответ или решение
Как предотвратить удаление определенных папок при использовании rsync
Использование rsync
для синхронизации файлов и папок — это широко распространенная практика среди администраторов и разработчиков. Однако, если у вас есть необходимость сохранить определенные директории без изменений, такие как .well-known
, используемая в контексте Let’s Encrypt, необходимо использовать специфические параметры командной строки rsync
. В этой статье мы подробно разберем, как это сделать.
Понимание параметров rsync
Перед тем как вдаваться в детали, давайте рассмотрим текущую команду rsync
, которую вы предоставили:
rsync -e "ssh -p $(SSH_PORT)" -P -rvzc --delete $(OUTPUTDIR)/ $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR) --cvs-exclude
Эта команда включает несколько параметров:
-e
: Определяет удаленный шелл (в данном случае SSH).-P
: Включает режим «продолжить» и отображение прогресса.-r
: Рекурсивная синхронизация директорий.-v
: Человекочитаемый вывод.-z
: Сжатие данных во время передачи.--delete
: Удаляет файлы на целевой стороне, которые отсутствуют на стороне источника.--cvs-exclude
: Использует стандартные правила исключения, аналогичные тем, что используют системы управления версиями CVS.
Исключение директории с помощью --exclude
Для того чтобы исключить определенные папки, вам нужно добавить параметр --exclude
с правильным путём к директории, которую вы хотите сохранить. Например, если вы хотите, чтобы папка .well-known
не удалялась, команда будет выглядеть так:
rsync -e "ssh -p $(SSH_PORT)" -P -rvzc --delete --exclude='.well-known' $(OUTPUTDIR)/ $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR) --cvs-exclude
Объяснение изменений:
- Добавленная опция
--exclude='.well-known'
говоритrsync
игнорировать эту папку при синхронизации. Таким образом,rsync
не вызовет ее удаление, даже если опция--delete
активирована.
Использование защиты с --filter
Если вам необходимо более строгий контроль над правилами исключения, можно воспользоваться фильтрами:
rsync -e "ssh -p $(SSH_PORT)" -P -rvzc --delete --filter="protect .well-known" $(OUTPUTDIR)/ $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR) --cvs-exclude
Здесь --filter="protect .well-known"
добавляет дополнительный уровень безопасности, защищая папку от удаления даже в случае использования опции --delete-excluded
.
Оптимизация rsync
Чтобы повысить эффективность работы rsync
, можно учитывать следующие практики:
- Используйте опцию
--bwlimit=RATE
для ограничения пропускной способности, если у вас есть ограничения по трафику. - Применяйте
--dry-run
перед фактическим выполнением команды, чтобы увидеть, какие файлы будут изменены или удалены, без внесения каких-либо изменений. - При необходимости используйте
--compress
(-z
) только при передачах по медленным соединениям, так как это может замедлить процесс на быстрых сетях.
Заключение
Использование rsync
для синхронизации файлов может быть мощным инструментом, если вы правильно настроите параметры. С помощью --exclude
и опций фильтрации вы можете защитить важные директории от удаления и сделать процесс более безопасным и предсказуемым. Не забывайте тестировать настройки с помощью --dry-run
перед выполнением команд, чтобы избежать случайных потерь данных.
Эти рекомендации помогут вам поддерживать ваши файлы в порядке и избежать удаления критически важных папок.