rsync tidak akan menghapus file pada tujuan

22

Saya mencoba untuk mencerminkan direktori yang berubah dari waktu ke waktu ke direktori lain. Masalah saya adalah rsync tidak menghapus file pada tujuan jika mereka tidak ada di direktori sumber lagi. Berikut ini adalah skrip 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

Berikut hasilnya:

+ 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

Seperti yang Anda lihat, file "a" masih ada di direktori tujuan setelah rsync berjalan untuk kedua kalinya, yang bukan yang saya butuhkan. Apakah saya menyalahgunakan opsi '--delete'?

halp
sumber
Hati-hati dengan / * di akhir direktori sumber. Itu akan menyebabkan rsync hanya mempertimbangkan file-file itu daripada direktori itu sendiri (dan tidak adanya file yang tidak ada lagi).
Walt Stoneburner

Jawaban:

9

Alasannya adalah karena Anda memanggil rsync di / tmp / 1 / b, yang tidak akan menganggap file / tmp / 1 / a sama sekali.

Niat Anda tampaknya adalah untuk rsync direktori / tmp / 1 / - jika Anda menggunakan "/ tmp / 1 /" sebagai sumber daripada file individual, ia akan melihat bahwa "a" telah dihapus dari direktori dan menghapus itu dari target.

Eric
sumber
23

Hapus *. Seperti disebutkan dalam halaman manual rsync --deleteopsi tidak bekerja dengan entri wildcard.

Gunakan ini sebagai gantinya:

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

"--delete Ini memberitahu rsync untuk menghapus file asing dari sisi penerima (yang tidak ada di sisi pengirim), tetapi hanya untuk direktori yang sedang disinkronkan. Anda harus meminta rsync untuk mengirim seluruh direktori (misalnya diratau dir/) tanpa menggunakan wildcard untuk isi direktori (misalnya dir/*) karena wildcard diperluas oleh shell dan rsync dengan demikian mendapat permintaan untuk mentransfer file individu, bukan direktori induk file . File yang dikecualikan dari transfer juga dikecualikan dari menjadi dihapus kecuali Anda menggunakan --delete-excludedopsi atau tandai aturan sebagai hanya cocok di sisi pengiriman (lihat menyertakan / mengecualikan pengubah di bagian ATURAN FILTER). "

Sameer
sumber
Ini secara fungsional sama dengan jawaban Sven mulai 2011.
Rowan Hawkins
8

Jika Anda mengubah baris rsync kedua ke rsync -a --delete $DIR1/ $DIR2(tanpa *) itu akan berfungsi. Alasannya adalah bahwa shell memperluas *ke nama file di direktori pertama, yang hanya b dalam kasus Anda, sehingga file yang hilang a tidak akan dianggap sama sekali oleh rsync, karena perintah yang dijalankan sebenarnya rsync -a --delete $DIR1/b $DIR2.

Sven
sumber