rsync nie usuwa plików w miejscu docelowym

22

Próbuję utworzyć kopię lustrzaną katalogu, który z czasem zmienia się w inny katalog. Mój problem polega na tym, że rsync nie usuwa plików w miejscu docelowym, jeśli nie istnieją one już w katalogu źródłowym. Oto skrypt demo:

#!/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

Oto wynik:

+ 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

Jak widać, plik „a” jest nadal obecny w katalogu docelowym po drugim uruchomieniu rsync, co nie jest tym, czego potrzebuję. Czy niewłaściwie używam opcji „--delete”?

halp
źródło
Uważaj na / * na końcu katalogów źródłowych. Spowoduje to, że rsync będzie uwzględniał tylko te pliki, a nie sam katalog (i brak plików, które już nie istnieją).
Walt Stoneburner,

Odpowiedzi:

9

Powodem jest to, że wywołujesz rsync na / tmp / 1 / b, co w ogóle nie uwzględnia pliku / tmp / 1 / a.

Wygląda na to, że masz zamiar zsynchronizować katalog / tmp / 1 / - jeśli użyjesz „/ tmp / 1 /” jako źródła, a nie poszczególnych plików, zauważysz, że „a” zostało usunięte z katalogu i usuń to z celu.

Eric
źródło
23

Usuń *. Jak wspomniano na stronach podręcznika rsync, --deleteopcja nie działa z wpisami symboli wieloznacznych.

Użyj tego zamiast:

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

„--delete To mówi rsyncowi, aby usunął zbędne pliki ze strony odbierającej (te, które nie są po stronie wysyłającej), ale tylko dla synchronizowanych katalogów. Musisz poprosić rsync o wysłanie całego katalogu (np. dirlub dir/) bez użycia symbolu wieloznacznego do zawartości katalogu (np. dir/*), ponieważ symbol wieloznaczny jest rozszerzany przez powłokę, a więc rsync otrzymuje żądanie przeniesienia pojedynczych plików, a nie katalogu macierzystego plików . Pliki wykluczone z transferu również są wykluczone z bycia usunięty, chyba że użyjesz tej --delete-excludedopcji lub nie zaznaczysz reguł jako pasujących tylko po stronie wysyłającej (zobacz modyfikatory włączania / wyłączania w sekcji ZASADY FILTRA). ”

Sameer
źródło
Jest to funkcjonalnie to samo, co odpowiedź Svena z 2011 roku.
Rowan Hawkins
8

Jeśli zmienisz drugą linię rsync na rsync -a --delete $DIR1/ $DIR2(bez *), to zadziała. Powodem jest to, że powłoka rozwija *nazwy plików w pierwszym katalogu, który w twoim przypadku jest tylko b, więc brakujący plik a nie będzie w ogóle brany pod uwagę przez rsync, ponieważ faktycznie wykonuje się polecenie rsync -a --delete $DIR1/b $DIR2.

Sven
źródło