rsync, ลบไฟล์ที่ได้รับด้านที่ถูกลบในการส่งด้าน (แต่อย่าลบทุกอย่าง)


9

ฉันต้องการใช้ rsync กับ ...

  • ลบไฟล์ในด้านการรับที่ถูกลบไปยังด้านการส่ง
  • อย่าลบไฟล์อื่น ๆ ที่อยู่ในไดเรกทอรี rsynced ทางด้านการรับ

ตัวอย่างเช่นสมมติว่าฉันมีไดเรกทอรีlocal-src:

ก่อน: local-srcภายในมี ...

a.txt
b.txt
c.txt

ไดเรกทอรีระยะไกลของฉันที่ฉันต้องการซิงค์กับเนื้อหาของการที่เรียกว่าlocal-srcremote-src

ก่อน: remote-srcจากระยะไกลประกอบด้วย ...

a.txt
b.txt
c.txt
d.txt
README.md

สมมติว่าฉันลบบางไฟล์ในlocal-src:

หลังจากลบ local-srcในพื้นที่:ภายในมี ...

c.txt

ฉันจะใช้ rsync อย่างไรเพื่อให้แน่ใจว่าไฟล์ที่ถูกลบที่ต้นทางนั้นจะถูกลบที่ปลายทางเช่นกัน แต่ไม่ต้องลบไฟล์อื่น ๆ ที่ปลายทาง ตัวอย่างเช่นฉันต้องการมีสิ่งต่อไปนี้ที่ปลายทาง:

หลังจากลบ LOCAL: remote-srcจากระยะไกลมี ...

c.txt
d.txt
README.md

นั่นคือa.txtและb.txtจะถูกลบจากระยะไกลเช่นกัน แต่d.txtและREADME.txtถูกทิ้งให้อยู่คนเดียว

มีวิธีใดบ้างที่จะทำให้สำเร็จด้วย rsync?

แก้ไข:คำตัดสินดูเหมือนว่าจะเป็นไปไม่ได้กับ rsync ฉันถูกถามว่าทำไมฉันจึงต้องการสิ่งนี้เพื่อแสดงให้เห็นถึงกรณีใช้ของฉัน:

สมมติว่าฉันมีเว็บเซิร์ฟเวอร์ บนเว็บเซิร์ฟเวอร์นั้นฉันมีไดเรกทอรีมากมายสมมติว่าฉันมีไดเรกทอรีAและpublic_htmlไดเรกทอรีที่ให้บริการเว็บไซต์ของฉัน Aสมมติว่าผมมีกระบวนการอัตโนมัติบางอย่างที่ผลิตแฟ้มในไดเรกทอรี ฉันต้องการที่จะ rsync (หรือซิงค์ใช้บางส่วนเครื่องมืออื่น ๆ ) ไฟล์ที่สร้างหรืออัปเดตในAไปยังpublic_htmlไดเรกทอรีโดยไม่ลบไฟล์โดยพลการอื่น ๆ public_htmlที่อาจจะอยู่ใน แน่นอนว่าฉันไม่ต้องการให้ rsync ลบเว็บไซต์ของฉันโดยไม่ได้ตั้งใจ

หาก rsync ไม่ใช่เครื่องมือสำหรับงานนี้มีคนอื่นรู้หรือไม่ว่าฉันสามารถทำได้


2
หลังจากอ่านคำถามของคุณอีกครั้งฉันไม่คิดว่าจะเป็นไปได้rsyncเพราะไม่มีวิธีที่จะรู้ว่าไฟล์ใดที่อยู่ในโฟลเดอร์ระยะไกลแล้ว คุณอาจต้องค้นหาเครื่องมืออื่น
Spack

rsync จะไม่ยอมให้คุณทำเช่นนี้ แต่ถ้าคุณสแกนไดเรกทอรีทั้งหมดทุกครั้งที่คุณลบไฟล์คุณสามารถทำให้พวกมันซิงค์กันได้ไม่ใช่แค่คำแนะนำ
Aadi Droid

1
ฉันเดาว่าคุณเคยคิดเรื่องนี้มาแล้ว แต่คุณไม่สามารถวางไฟล์เหล่านี้ในไดเรกทอรีย่อย (หรือที่อื่น) และอ้างอิงจาก public_html วิธีนี้จะทำให้คุณมีหนึ่งไดเรกทอรีที่ซิงค์ได้ง่ายและชัดเจนโดยไม่มีผลกับไฟล์ในส่วนอื่น ๆ ของระบบไฟล์ของเว็บเซิร์ฟเวอร์
MattJenko

คำตอบ:


2

สิ่งที่คุณต้องการจะทำมีเหตุผล แต่การใช้rsyncเพื่อทำด้วยตัวเองไม่ได้ ดังนั้นคำตอบคือไม่มี

เหตุผลง่าย: rsyncไม่เก็บประวัติของสิ่งที่อยู่ในแต่ละไดเรกทอรีและไม่มีทางรู้ว่าต้องลบอะไรและไม่ทำอะไร ไม่ได้หากไม่มีการสนับสนุนเพิ่มเติม

คุณควรถามตัวเองว่าทำไมคุณถึงชอบทำสิ่งนี้rsyncและทำให้ชัดเจนยิ่งขึ้น มีโปรแกรมอื่น ๆ ที่ใช้librsync1.soที่ฉลาดกว่า


ด้วยข้อ จำกัด ที่ผ่อนคลายที่คุณไม่ต้องการrsyncต่อคุณสามารถดูrdiff-backup :

mkdir a
touch a/xx
touch a/yy
rdiff-backup a b
ls b 

นี้แสดงให้เห็นxxและอยู่ในyyb

touch b/zz
rm a/xx
rdiff-backup a b

นี้แสดงให้เห็นxxและอยู่ในzz ยังเก็บไดเรกทอรีไว้เพื่อให้คุณสามารถย้อนกลับการเปลี่ยนแปลงใด ๆ ได้คุณควรล้างข้อมูลนี้เป็นประจำโดยใช้คำสั่ง (ตัวอย่างคือพร้อมกับไฟล์โลคัลเพื่อแสดงข้อมูลพิเศษในเป้าหมายไม่ได้ถูกลบ แต่ rdiff-backup ทำงานบนเครือข่ายได้เช่นกัน)brdiff-backuprdiff-backup-databrdiff-backup


อีกทางเลือกหนึ่งคือการตั้งค่าระบบควบคุมการแก้ไขแบบกระจาย (mercurial, bazaar, git) ด้วย Mercurial เช่นคุณสามารถมีสคริปต์ (ฉันใช้ Makefile สำหรับสิ่งนั้น) ซึ่งผลักดันการเปลี่ยนแปลงทั้งหมดไปยังเซิร์ฟเวอร์แล้วทำการอัปเดตไฟล์ที่เช็คเอาต์ที่นั่นละเว้นไฟล์เพิ่มเติมใด ๆ ที่อยู่บนเซิร์ฟเวอร์ระยะไกล (แต่มี ไม่ได้อยู่ภายใต้การควบคุมการแก้ไข)

บนเซิร์ฟเวอร์คุณจะทำ:

hg init
hg add file_list_excluding_that_should_not_should_be_deleted_if_not_on_client
hg commit -m "initial setup"

เกี่ยวกับลูกค้า:

hg clone ssh://username@server/dir_to_repository

ตอนนี้ถ้าคุณลบไฟล์บนไคลเอนต์และทำ:

hg commit -m "removed file"
ssh username@server "cd dir_to_repository; hg update --clean"

ไฟล์ที่ถูกลบของคุณถูกลบบนเซิร์ฟเวอร์ แต่ข้อมูลอื่น ๆ (ไม่ได้เพิ่มในที่เก็บ) จะไม่ถูกลบ


ฉันยอมรับได้ว่า rsync จะไม่ทำเช่นนี้ แต่ฉันไม่ยอมรับว่าสิ่งนี้จะเป็นไปไม่ได้ถ้า rsync รู้ว่าในด้านการส่งไฟล์ใดถูกลบไปแล้วทำไมมันถึงส่งข้อมูลนั้นไปยังฝ่ายรับไม่ได้ หลังจากเปรียบเทียบความสดใหม่ฉันไม่เห็นสาเหตุที่ฝ่ายรับไม่สามารถลบไฟล์ที่ระบุว่าถูกลบในส่วนต่างได้โดยไม่ต้องลบทุกอย่างในไดเรกทอรี การลบไฟล์ผู้บริสุทธิ์อื่น ๆ (ไม่ได้ลบแหล่งที่มา) ในไดเรกทอรีดูเหมือนว่าไม่สมเหตุสมผลสำหรับฉัน
Heather Miller

ไม่ว่าในกรณีใดเหตุผลที่ฉันต้องการมีดังนี้ ฉันมีไดเรกทอรีลองเรียกมันAว่ากระบวนการบางอย่างเป็นอัตโนมัติและสร้างไฟล์ขึ้นโดยอัตโนมัติ ฉันมีเว็บเซิร์ฟเวอร์และฉันต้องการให้ไฟล์ภายในAถูกซิงค์กับpublic_htmlไดเรกทอรีของเว็บเซิร์ฟเวอร์แน่นอนโดยไม่ต้องลบทุกอย่างในpublic_htmlโฟลเดอร์ของเว็บเซิร์ฟเวอร์ หากใครมีความคิดใด ๆ ในการบรรลุเป้าหมายนี้ด้วยเครื่องมืออื่นมันจะเป็นมากกว่าการต้อนรับ ฉันจะอัปเดตคำถามของฉันเพื่อสะท้อนสิ่งนี้
Heather Miller

เพื่อชี้แจงความคิดเห็นแรกของฉันด้านบน - ฉันควรจะพูดว่า "ฉันไม่เห็นด้วยว่าสิ่งนี้ควรเป็นไปไม่ได้ด้วยเครื่องมืออย่าง rsync" โดยสังหรณ์ใจดูเหมือนว่ามันจะไม่ยากเกินกว่าจะบรรลุได้
Heather Miller

อืมโอเค. ฉันคิดว่าฉันจะเห็นในตอนนี้ - rsync จะรู้ได้อย่างไรว่าบางสิ่งถูกลบในlocal-srcไดเรกทอรีโดยไม่ต้องมีกระบวนการเฝ้าดูไดเรกทอรีนั้นเพื่อทำการเปลี่ยนแปลง บางทีนี่อาจจะยาก
Heather Miller

@HeatherMiller เหมือนที่ฉันเขียนคำขอของคุณสมเหตุสมผล แต่rsyncไม่ใช่เครื่องมือ โปรดทราบว่าsyncในrsyncนั้นมาจากการซิงโครไนซ์และนั่นไม่ใช่สิ่งที่คุณต้องการจะทำ ในการพัฒนาrsyncโฟกัสนั้นมีประสิทธิภาพ (ลดขนาด) การถ่ายโอนข้อมูล เครื่องมืออื่น ๆ เช่นrdiff-backup(และเป็นไปได้cvsup) ได้ใช้เทคนิคในการทำเช่นนั้น แต่สร้างขึ้นด้วยคุณสมบัติเพิ่มเติม
Anthon

1

ฉันไม่คิดว่ามันจะเป็นไปได้หากไม่รวมไฟล์ที่อยู่ด้านรับอย่างชัดเจนโดยเป็นส่วนหนึ่งของคำสั่ง rsync ดูส่วน man page สำหรับ rsync: "กฎต่อไปและลบ"

หากไม่มีตัวเลือกการลบกฎต่อไดเรกทอรีจะเกี่ยวข้องกับด้านการส่งเท่านั้นดังนั้นคุณสามารถแยกไฟล์ผสานเองได้โดยไม่ส่งผลกระทบต่อการถ่ายโอน เพื่อให้ง่ายตัวปรับเปลี่ยน 'e' จะเพิ่มการยกเว้นนี้ให้คุณดังที่เห็นในคำสั่งเทียบเท่าสองคำสั่งนี้:

          rsync -av --filter=': .excl' --exclude=.excl host:src/dir /dest
          rsync -av --filter=':e .excl' host:src/dir /dest

อย่างไรก็ตามหากคุณต้องการลบทางด้านรับและคุณต้องการให้มีการแยกไฟล์บางส่วนออกจากการลบคุณจะต้องแน่ใจว่าด้านการรับรู้ว่าไฟล์ใดที่จะไม่รวม วิธีที่ง่ายที่สุดคือการรวมไฟล์ต่อไดเรกทอรีในการถ่ายโอนและใช้ - ลบหลังจากนี้เพื่อให้แน่ใจว่าด้านการรับได้รับกฎการยกเว้นเดียวกันทั้งหมดเป็นด้านการส่งก่อนที่จะพยายามลบอะไร:

          rsync -avF --delete-after host:src/dir /dest

อย่างไรก็ตามหากไฟล์ผสานไม่ได้เป็นส่วนหนึ่งของการถ่ายโอนคุณจะต้องระบุกฎการยกเว้นทั่วโลกบางอย่าง (เช่นระบุไว้ในบรรทัดคำสั่ง) หรือคุณจะต้องบำรุงรักษาไฟล์ผสานไดเรกทอรีของคุณเองใน รับด้าน ตัวอย่างแรกคือสิ่งนี้ (สมมติว่าไฟล์. rules ระยะไกลแยกตัวเอง):

   rsync -av --filter=’: .rules’ --filter=’. /my/extra.rules’
      --delete host:src/dir /dest

ในตัวอย่างข้างต้นไฟล์ extra.rules สามารถส่งผลต่อทั้งสองด้านของการถ่ายโอน แต่ (บนฝั่งที่ส่ง) กฎจะยอมให้กฎที่รวมจากไฟล์. rules ได้เนื่องจากกฎเหล่านั้นถูกระบุหลังจากกฎการรวมไดเรกทอรีต่อ

ในตัวอย่างสุดท้ายหนึ่งด้านระยะไกลไม่รวมไฟล์ .rsync-filter จากการถ่ายโอน แต่เราต้องการใช้ไฟล์ .rsync-filter ของเราเองเพื่อควบคุมสิ่งที่ถูกลบในด้านการรับ ในการทำเช่นนี้เราจะต้องยกเว้นไฟล์ต่อการรวมไดเรกทอรี (เพื่อไม่ให้ถูกลบ) จากนั้นใส่กฎลงในไฟล์ในเครื่องเพื่อควบคุมสิ่งที่ไม่ควรถูกลบ ชอบหนึ่งในคำสั่งเหล่านี้:

       rsync -av --filter=':e /.rsync-filter' --delete \
           host:src/dir /dest
       rsync -avFF --delete host:src/dir /dest

0

หากฉันเข้าใจถูกต้อง--excludeอาจเป็นสิ่งที่คุณกำลังมองหา:

$ ls src dst
dst:
a.txt  b.txt  c.txt  d.txt  README.md

src:
c.txt
$ rsync --update --delete --recursive --exclude="d.txt" --exclude="README.md" src/ dst
$ ls src dst
dst:
c.txt  d.txt  README.md

src:
c.txt

ไม่เลย ฉันไม่ต้องการให้แสดงรายการไฟล์ทั้งหมดที่ฉันต้องการแยกด้วยตนเอง ฉันแค่อยาก rsync เท่านั้นที่จะลบไฟล์ที่ฉันได้ลบที่แหล่งที่มา - ฉันไม่ควรต้องรู้ที่มาว่าไฟล์ที่เป็นไปได้อื่น ๆ ที่มีอยู่ในไดเรกทอรีเดียวกันที่ปลายทาง
Heather Miller

0

ฉันมีคำตอบสำหรับสิ่งนั้น ฉันคิดว่ามันใช้งานได้ และมันใช้งานได้สำหรับฉัน ก่อนอื่นคุณควรต้องrsyncรีโมตไฟล์เป็นไฟล์โลคัล จากนั้นด้านในเครื่องมีไฟล์ทั้งหมด

sudo rsync -r -a -v --delete /root@xx.xx.xx.xx:/remote_dir/ /local_dir/

ตอนนี้ในด้านท้องถิ่น

a.txt
b.txt
c.txt
d.txt
README.md

จากนั้นคุณสามารถลบไฟล์หรือทำสิ่งที่คุณต้องการ (ในด้านท้องถิ่น) ในคำถามของคุณคุณลบไฟล์เหล่านี้

ไฟล์ที่ถูกลบ

a.txt
b.txt

หลังจากนั้นคุณสามารถrsyncโลคัลไฟล์ไปยังรีโมตจากนั้นทั้งสองฝั่งมีไฟล์เดียวกัน

sudo rsync -r -a -v --delete /local_dir/ root@xx.xx.xx.xx:/remote_dir/

มันให้

c.txt
d.txt
README.md

ไฟล์ในด้านระยะไกลและด้านท้องถิ่น (โดยใช้--deleteมันจะลบไฟล์อื่น ๆ ในด้านระยะไกลที่ไม่ตรงกับด้านท้องถิ่น )

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.