Я пытаюсь отразить каталог, который со временем меняется, на другой каталог. Моя проблема в том, что 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
.