Назад | Перейти на главную страницу

rsync не удаляет файлы по назначению

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

#!/bin/sh

set -x

DIR1=/tmp/1
DIR2=/tmp/2

rm -rf $DIR1
rm -rf $DIR2

mkdir $DIR1
mkdir $DIR2

echo "foo" > $DIR1/a
echo "bar" > $DIR1/b

rsync -a $DIR1/* $DIR2

rm -f $DIR1/a

rsync -a --delete $DIR1/* $DIR2

ls -1 $DIR2

Вот результат:

+ DIR1=/tmp/1
+ DIR2=/tmp/2
+ rm -rf /tmp/1
+ rm -rf /tmp/2
+ mkdir /tmp/1
+ mkdir /tmp/2
+ echo foo
+ echo bar
+ rsync -a /tmp/1/a /tmp/1/b /tmp/2
+ rm -f /tmp/1/a
+ rsync -a --delete /tmp/1/b /tmp/2
+ ls -1 /tmp/2
a
b

Как видите, файл «a» по-прежнему присутствует в каталоге назначения после того, как rsync запускается во второй раз, что мне не нужно. Неправильно ли я использую параметр --delete?

Удалить *. Как упоминалось на страницах руководства rsync, --delete опция не работает с подстановочными знаками.

Используйте вместо этого:

rsync -a --delete $DIR1/ $DIR2/

"--delete Это указывает rsync на удаление посторонних файлов с принимающей стороны (тех, которые не находятся на стороне отправителя), но только для каталогов, которые синхронизируются. Вы должны были попросить rsync отправить весь каталог (например, dir или dir/) без использования подстановочного знака для содержимого каталога (например, dir/*), поскольку подстановочный знак расширяется оболочкой, и rsync, таким образом, получает запрос на передачу отдельных файлов, а не родительского каталога файлов. Файлы, исключенные из передачи, также не подлежат удалению, если вы не используете --delete-excluded или отметьте правила как соответствующие только на отправляющей стороне (см. модификаторы include / exclude в разделе FILTER RULES). "

Причина в том, что вы вызываете rsync на / tmp / 1 / b, который вообще не будет рассматривать файл / tmp / 1 / a.

Похоже, вы намерены выполнить синхронизацию каталога / tmp / 1 / - если вы используете «/ tmp / 1 /» в качестве источника, а не отдельные файлы, он заметит, что «a» был удален из каталога, и удалит это от цели.

Если вы измените вторую строку rsync на rsync -a --delete $DIR1/ $DIR2 (без *) это будет работать. Причина в том, что оболочка расширяет * к именам файлов в первом каталоге, который в вашем случае равен только b, поэтому отсутствующий файл a вообще не будет рассматриваться rsync, поскольку выполняемая команда на самом деле rsync -a --delete $DIR1/b $DIR2.