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

22

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

halp
источник
Следите за / * в конце исходных каталогов. Это заставит rsync рассматривать только эти файлы, а не сам каталог (и отсутствие файлов, которые больше не существуют).
Уолт Стоунбернер

Ответы:

9

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

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

Эрик
источник
23

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

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

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

«--delete Это говорит rsync об удалении посторонних файлов с принимающей стороны (тех, которые не на отправляющей стороне), но только для синхронизируемых каталогов. Вы, должно быть, попросили rsync отправить весь каталог (например, dirили dir/) без использования подстановочного знака для содержимого каталога (например dir/*), поскольку подстановочный знак раскрывается оболочкой, и, таким образом, rsync получает запрос на передачу отдельных файлов, а не родительский каталог файлов . Файлы, исключенные из передачи, также исключаются из удаляется, если вы не используете --delete-excludedопцию или не помечаете правила как совпадающие только на отправляющей стороне (см. модификаторы include / exclude в разделе ПРАВИЛА ФИЛЬТРА). "

Самир
источник
Это функционально совпадает с ответом Свена от 2011 года.
Роуэн Хокинс,
8

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

Свен
источник