Опция Rsync –delete не удаляет файлы в целевой директории

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

Я пытаюсь использовать опцию --delete в rsync, чтобы удалить файлы в целевом каталоге, которые отсутствуют в исходном каталоге

Вот команда, которую я использую:

rsync -avz --ignore-existing --recursive --delete /var/www/* [email protected]:/var/www

Так что мой вопрос в том, как я могу удалить все файлы в целевом каталоге, которые отсутствуют в исходном каталоге?

Используйте эту команду:

rsync --archive --verbose --compress --ignore-existing --delete /var/www/ [email protected]:/var/www

Вам не нужен символ “*” и не следует его использовать.

Чтобы исключить/включить файлы или каталоги, вы должны использовать эти параметры:

--exclude 'to_exclude*'
--include 'to_include*'

Ваша команда не работала, потому что, когда вы использовали /var/www/* в качестве источника, ваша оболочка выполняет расширение паттерна, т.е. оболочка расширяет * на все файлы в этом каталоге и копирует файлы по одному, так что отдельные файлы становятся источниками, а не родительским каталогом.

Так что, если вы используете /var/www/*, то вам не нужна опция --recursive, так как * вызовет копирование файлов (вместе с любыми каталогами с их содержимым), а не родительского каталога, который содержит файлы. По той же причине --delete не работает, так как --delete удалит файлы из целевого каталога, которые отсутствуют в исходном каталоге, но вы копируете файлы, поэтому он не удаляет файлы (как ожидалось).

Это сделает вам более ясно:

/foo$ ls -l
-rw-rw-r-- 1 user user    0 Apr 16 17:56 egg
-rw-rw-r-- 1 user user    0 Apr 16 17:56 spam
drwxrwxr-x 2 user user 4096 Apr 16 18:14 test

/bar$ ls -l
-rw-rw-r-- 1 user user 0 Apr 16 17:56 egg
-rw-rw-r-- 1 user user 0 Apr 16 18:13 lion
-rw-rw-r-- 1 user user 0 Apr 16 17:56 spam

$ rsync -avz --ignore-existing --recursive --delete 
/foo/* /bar/

+ rsync -avz --ignore-existing --recursive --delete 
/foo/egg /foo/spam /foo/test /bar/

sending incremental file list
test/
test/hello

sent 173 bytes  received 39 bytes  424.00 bytes/sec
total size is 0  speedup is 0.00

/bar$ ls -l
-rw-rw-r-- 1 user user    0 Apr 16 17:56 egg
-rw-rw-r-- 1 user user    0 Apr 16 18:13 lion
-rw-rw-r-- 1 user user    0 Apr 16 17:56 spam
drwxrwxr-x 2 user user 4096 Apr 16 18:14 test

Как видите, я использовал источник как /foo/*, таким образом выполняется команда rsync

rsync -avz --ignore-existing --recursive --delete /foo/egg 
/foo/spam /foo/test /bar/

с *, заставляющим оболочку расширять его и делать все файлы индивидуально источниками, а не родительский каталог целиком (и вам также не нужна --recursive в этом случае).

Так что, если вы хотите, чтобы --delete работало, выполните это так:

rsync -avz --ignore-existing --recursive --delete 
/var/www/ [email protected]:/var/www/

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

Проблема: Опция --delete в rsync не удаляет файлы в целевом каталоге

Введение

Команда rsync является мощным инструментом для синхронизации файлов и каталогов между локальными и удалёнными системами. Однако иногда пользователи сталкиваются с проблемами, связанными с опцией --delete, которая предназначена для удаления файлов в целевом каталоге, отсутствующих в исходном каталоге. В данной статье мы подробно рассмотрим, почему опция --delete может не работать в вашем случае и как правильно использовать команду rsync.

Описание проблемы

Вы используете следующую команду:

rsync -avz --ignore-existing --recursive --delete /var/www/* user@remote:/var/www

Ваша цель — удалить файлы в целевом каталоге /var/www на удалённом сервере, которые не присутствуют в локальном каталоге /var/www. Однако, как вы заметили, выполнение данной команды не приводит к удалению ожидаемых файлов.

Причина неработоспособности

Ключевым моментом вашей команды является использование шаблона *:

  • Использование /var/www/* ведет к тому, что оболочка (shell) расширяет данный шаблон в список всех файлов и каталогов в директории /var/www.
  • В результате, rsync обрабатывает каждый файл и каталог как отдельный аргумент, вместо того чтобы рассматривать весь каталог var/www в целом. Это находит отражение в том, что --delete не может корректно определить файлы для удаления.

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

Решение проблемы

Чтобы исправить ситуацию и обеспечить работу опции --delete, вам нужно изменить синтаксис команды. Уберите звездочку (*) и добавьте завершающий слэш к исходному каталогу. Ваш исправленный вызов команды будет выглядеть так:

rsync -avz --ignore-existing --delete /var/www/ user@remote:/var/www/

Объяснение изменений:

  • Использование /var/www/ (с завершающим слэшем) указывает rsync, что необходимо синхронизировать содержимое каталога, вместо обработки отдельных файлов.
  • Удаление опции --recursive в данном случае не требуется, поскольку, когда указаны директории, rsync по умолчанию работает рекурсивно.

Дополнительные настройки

Если вам необходимо исключить или включить определенные файлы и каталоги, для этого подойдут параметры --exclude и --include. Например:

rsync -avz --delete --exclude 'to_exclude*' --include 'to_include*' /var/www/ user@remote:/var/www/

Заключение

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

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

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