ย้ายไฟล์และลบไดเรกทอรีด้วย rsync หรือไม่


17

เมื่อเร็ว ๆ นี้ฉันต้องการลบไฟล์จำนวนมาก (มากกว่า 1 ล้านไฟล์) และฉันได้อ่าน:

rsync -av --delete `mktemp -d`/ ~/source && rmdir ~/source

rm -rfเป็นหนึ่งในวิธีที่ดีที่สุดมากที่สุดที่จะทำเช่นนั้นและฉันสามารถรับรองว่ามันเร็วกว่า

ฉันไม่ใช่ผู้เชี่ยวชาญในเรื่องนี้ แต่จากความเข้าใจของฉันแล้วเหตุผลที่ประสิทธิภาพของ rsync มีบางอย่างที่ต้องทำตามวิธีที่รายการไฟล์ (LIFO แทนที่จะเป็น FIFO ที่ฉันคิดว่า) ตอนนี้ปัญหาคือฉันต้องย้ายไฟล์จำนวนมากด้วยวิธีที่มีประสิทธิภาพ หลังจากค้นหาแล้วฉันก็พบสิ่งนี้:

rsync -av --ignore-existing --remove-source-files ~/source ~/destination

ขณะนี้ลบทั้งหมดย้ายไฟล์ใน~/sourceไดเรกทอรียังคงมี เนื่องจากฉันมีโครงสร้างไดเรกทอรีคล้ายกับ "round-robin" จำนวนfiles/directoriesใกล้เคียงกับ 1 ดังนั้นฉันจึงถูกบังคับให้เรียกใช้คำสั่งแรกอีกครั้งเพื่อกำจัดไดเรกทอรีทั้งหมด:

rsync -av --ignore-existing --remove-source-files ~/source ~/destination && \
rsync -av --delete `mktemp -d`/ ~/source && rmdir ~/source

ตรงmvจะเสร็จแทบทันที แต่~/destinationไดเรกทอรีของฉันมีไฟล์ที่ควรเก็บไว้ดังนั้นจึงmvไม่ใช่ตัวเลือก ฉันพบตัวเลือก--prune-empty-dirsและ--forcersync แต่ดูเหมือนจะไม่ทำงานอย่างที่ฉันคาดหวัง:

--force                 force deletion of directories even if not empty
--prune-empty-dirs      prune empty directory chains from the file-list
--remove-source-files   sender removes synchronized files (non-dirs)

มีวิธีที่จะเลียนแบบการเคลื่อนไหวด้วย rsync ในครั้งเดียวหรือไม่?


2
หากคุณไม่ได้รับคำตอบที่นี่ลองโพสต์ในรายการ rsync พวกเขามีประโยชน์มาก list.samba.org/mailman/listinfo/rsync
Joe

คำตอบ:


7

ฉันพบกระทู้นี้ใน stackoverflow ชื่อ: การลบโฟลเดอร์ด้วย rsync“ ย้าย”? ซึ่งถามคำถามเดียวกันเป็นหลัก หนึ่งในคำตอบที่แนะนำให้ทำrsyncคำสั่ง in 2 เนื่องจากปรากฏว่าไม่มีคำสั่งเดียวที่สามารถทำการย้าย / ลบไฟล์และไดเรกทอรีต้นทางได้สำเร็จ

$ rsync -av --ignore-existing --remove-source-files source/ destination/ && \
  rsync -av --delete `mktemp -d`/ source/ && rmdir source/

หรือคุณสามารถทำได้โดยใช้คำสั่งนี้:

$ rsync -axvvES --remove-source-files source_directory /destination/ && \
  rm -rf source_directory

ไม่เหมาะ แต่ทำหน้าที่ได้ดี


ใช่ฉันเองที่ตอบคำถามนั้น (และ "วิธีแก้ปัญหา" แบบเดียวกันก็อยู่ในคำถามนี้ด้วย) = P
Alix Axel

@AlixAxel - ฮาขอโทษฉันไม่ได้สังเกตเห็นว่าคุณตอบว่า โอ้ดี ฉันจะลบคำตอบนี้ได้ไหม?
slm

3
ใช้ไปยังไดเรกทอรีพรุนไม่รู้สึกที่เหมาะสมและมีเสมอกับอันตรายrsync rm -rfฉันขอแนะนำขั้นตอนที่ 2 ให้เป็น:find source/ -d -type d -exec rmdir {} \;
zany

2
ฉันแค่รู้สึกว่าถูกบังคับให้เพิ่มไม่เคยใช้-deleteและ--remove-source-filesในคำสั่ง rsync เดียว (ตัวอย่างข้างต้นใช้ได้เลยนี่คือแทนเจนต์) หากคุณขัดจังหวะจากนั้นดำเนินการสิ่งที่ฉันอธิบายอีกครั้งคุณจะสูญเสียไฟล์ที่ถ่ายโอน ซึ่งฉันทำมาก่อน :(
Sridhar Sarnobat

เมื่อทำความสะอาดด้วยfindฉันชอบสิ่งนี้: find source/ -type d -empty -delete มันให้ความรู้สึกแปลก ๆ แก่ฉันว่ามันจะไม่ปิดบังทุกอย่าง
greyfade

10

จากความคิดเห็นของ zany ถึงคำตอบของ slm ( ย้ายไฟล์และลบไดเร็กตอรี่ด้วย rsync? ) ฉันอยากจะแนะนำ 2 คำสั่งนี้เป็นคำตอบ:

rsync -av --ignore-existing --remove-source-files source/ destination/ && \
find source/ -depth -type d  -empty -exec rmdir "{}" \;

ข้อได้เปรียบคือเช่น zany กล่าวว่ายังมีอันตรายบางอย่างที่เกี่ยวข้องกับการใช้ rm -rf หากคุณไม่ได้ทำให้ถูกต้องหรือสำหรับผู้เริ่มต้น

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


ทำไมไม่เพียง-deleteแทน-exec rmdir {} \;?
แกะที่บิน

@flying_sheep เห็นความคิดเห็นของผู้ใช้ 7000 ในคำตอบของซิม: เมื่อ rsync ist ถูกขัดจังหวะคุณสามารถคลายไฟล์ได้
mit

เมื่อ rsync ถูกขัดจังหวะการค้นหาไม่เคยเริ่มต้นหรือไม่ ดังนั้น -delete ใน rsync อันที่สองจึงไม่เป็นปัญหา แต่ -delete ยังลบไฟล์แทน rmdir ไม่เคยลบไฟล์เฉพาะไดเรกทอรี ทั้ง (-delete และ rmdir) ตรวจสอบไดเรกทอรีหากมันว่างเปล่าก่อนที่จะลบ
benba

นอกจากนี้ man pages บอกว่าคุณควรใช้ -execdir แทนที่จะเป็น -exec ...
benba

2

สิ่งนี้จะทำงานในขั้นตอนเดียว บันทึกส่วนท้าย / slash / บนทั้งเส้นทางต้นทางและปลายทาง

rsync \
    -ruval \
    --ignore-existing \
    --remove-source-files \
    --prune-empty-dirs \ 
    /source/path/ /target/path/

ผมสะท้อนความระมัดระวังจาก user7000 จะไม่ใช้--deleteและร่วมกันในสายเดียวกัน--remove-source-files rsyncหากการดำเนินการล้มเหลวหรือถูกขัดจังหวะและมีการโทรซ้ำคุณจะสูญเสียข้อมูล หากมีข้อสงสัยให้ใช้--dry-runตัวเลือกเพื่อดูว่าจะทำอะไร


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