Rsync - ตัวเลือกการลบไม่ได้ลบไฟล์ในไดเรกทอรีเป้าหมาย


14

ฉันกำลังพยายามใช้--deleteตัวเลือกในrsyncการลบไฟล์ในไดเรกทอรีเป้าหมายซึ่งไม่มีอยู่ในไดเรกทอรีเดิม

นี่คือคำสั่งที่ฉันใช้:

rsync -avz --ignore-existing --recursive --delete /var/www/* root@mydomaintest.com:/var/www

ดังนั้นคำถามของฉันคือฉันจะลบไฟล์ทั้งหมดในไดเรกทอรีเป้าหมายที่ไม่มีอยู่ในไดเรกทอรีเดิมได้อย่างไร

คำตอบ:


14

ใช้คำสั่งนี้:

rsync --archive --verbose --compress --ignore-existing --delete /var/www/ root@mydomaintest.com:/var/www

คุณไม่จำเป็นต้องมี "*" และไม่ควรใช้เช่นกัน

หากต้องการยกเว้น / รวมไฟล์หรือไดเรกทอรีคุณควรใช้พารามิเตอร์นี้:

--exclude 'to_exclude*'
--include 'to_include*'

โอเคขอให้ฉันลองทำสิ่งนี้ :)
user2028856

2
ดังนั้น "*" ที่ทำให้คำสั่ง - ลบไม่ทำงาน?
user2028856

2
นั่นคือลักษณะที่ปรากฏ :)
AB

3
--recursiveมีมากเกินไปเพราะมีตัวเลือก-aอยู่แล้ว
Temak

1
"*" อาจมีความสำคัญในบางกรณีเนื่องจากมันไม่รวมไฟล์ / ไดเรกทอรีที่ขึ้นต้นด้วย "." ตัวอย่างเช่นฉันใช้เมื่อใช้ rsync เพื่อคัดลอกไดเรกทอรีไว้ภายใต้ git จากเครื่องพัฒนาไปยังเครื่องผลิต ฉันไม่ต้องการซิงค์ไดเรกทอรีที่เก็บ. git หรือไฟล์เช่น. gitignore เพียงแผนผังการทำงานรวมถึงไฟล์ที่ระดับบนสุดและไดเรกทอรีย่อย
sootsnoot

14

คำสั่งของคุณไม่ทำงานเพราะเมื่อคุณใช้/var/www/*เป็นแหล่งที่มาเชลล์ของคุณกำลังทำงานแบบกลมเช่นเชลล์กำลังขยาย*ไปยังไฟล์ทั้งหมดในไดเรกทอรีนั้นและการคัดลอกไฟล์ทีละตัวดังนั้นที่นี่แต่ละไฟล์กลายเป็นแหล่งที่มาแทนที่จะเป็น ไดเรกทอรีหลัก

ดังนั้นหากคุณใช้งาน/var/www/*คุณไม่จำเป็นต้องมี--recursiveตัวเลือกที่*จะทำให้ไฟล์ถูกคัดลอก (รวมถึงไดเรกทอรีที่มีเนื้อหา) ไม่ใช่ไดเรกทอรีหลักที่มีไฟล์ เนื่องจากเหตุผลเดียวกัน--deleteไม่ทำงานเช่นเดียวกับที่--deleteจะลบไฟล์ออกจากไดเรกทอรีปลายทางที่ไม่ได้อยู่ในไดเรกทอรีต้นทางแต่คุณกำลังคัดลอกไฟล์เพื่อไม่ให้ลบไฟล์ (โดยคาดหมาย)

สิ่งนี้จะทำให้คุณชัดเจนยิ่งขึ้น:

/foo$ ls -l
-rw-rw-r-- 1 user user    0 Apr 16 17:56 egg
-rw-rw-r-- 1 user user    0 Apr 16 17:56 spam
drwxrwxr-x 2 user user 4096 Apr 16 18:14 test


/bar$ ls -l
-rw-rw-r-- 1 user user 0 Apr 16 17:56 egg
-rw-rw-r-- 1 user user 0 Apr 16 18:13 lion
-rw-rw-r-- 1 user user 0 Apr 16 17:56 spam


$ rsync -avz --ignore-existing --recursive --delete 
/foo/* /bar/

+ rsync -avz --ignore-existing --recursive --delete 
/foo/egg /foo/spam /foo/test /bar/

sending incremental file list
test/
test/hello

sent 173 bytes  received 39 bytes  424.00 bytes/sec
total size is 0  speedup is 0.00


/bar$ ls -l
-rw-rw-r-- 1 user user    0 Apr 16 17:56 egg
-rw-rw-r-- 1 user user    0 Apr 16 18:13 lion
-rw-rw-r-- 1 user user    0 Apr 16 17:56 spam
drwxrwxr-x 2 user user 4096 Apr 16 18:14 test

อย่างที่คุณเห็นฉันใช้แหล่งที่มา/foo/*ด้วยเหตุนี้rsyncคำสั่งที่ถูกดำเนินการก็คือ

rsync -avz --ignore-existing --recursive --delete /foo/egg 
/foo/spam /foo/test /bar/

ด้วย*การสร้างเชลล์เพื่อขยายและสร้างไฟล์ทั้งหมดแยกต่างหากเป็นซอร์สอาร์กิวเมนต์ไม่ใช่ไดเร็กทอรีพาเรนต์ทั้งหมด (และคุณไม่ต้องการ--recursiveในกรณีนี้)

ดังนั้นหากคุณต้องการ--deleteทำงานให้เรียกใช้เป็น:

rsync -avz --ignore-existing --recursive --delete 
/var/www/ root@mydomaintest.com:/var/www/

4
คำอธิบายที่ดีเลิศชี้ให้เห็นปัญหาจริง: ใช้ '*' เพื่อขยายรายการแหล่งที่มา
Antonio Bardazzi

ตามที่ระบุไว้ในความคิดเห็นของฉันเกี่ยวกับคำตอบที่ยอมรับ * อาจมีประโยชน์ในการแยกสิ่งต่าง ๆ เช่นไฟล์และไดเรกทอรีที่ขึ้นต้นด้วย "." แม้ว่าตามที่ระบุไว้นี้หมายถึงไฟล์และไดเรกทอรีที่ถูกลบออกจากระดับสูงสุดในแหล่งที่มาจะไม่ถูกลบออกจากไดเรกทอรีปลายทาง สำหรับตัวฉันเองฉันไม่สนใจว่าไฟล์ระดับบนสุดจะถูกลบออกจากปลายทางอย่างถูกต้องหรือไม่เฉพาะไฟล์ที่อยู่ใต้ไดเรกทอรีย่อยเท่านั้น การลบไดเรกทอรีย่อยระดับบนสุดมีโอกาสน้อยกว่าการเพิ่มไดเรกทอรีและฉันยินดีที่จะใช้ rm -r ด้วยตนเองในปลายทางในกรณีที่ไม่น่าเป็นไปได้
sootsnoot
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.