วิธีการคัดลอกไดเรกทอรีด้วยการรักษาฮาร์ดลิงก์?


40

วิธีย้ายไดเรกทอรีที่มีไฟล์เหมือนกันจากพาร์ทิชั่นหนึ่งไปยังอีกพาร์ติชั่น?

สมมติว่าเรามีพาร์ติชั่นติดตั้ง/mnt/Xพร้อมกับไดเรกทอรีแชร์ไฟล์ด้วยฮาร์ดลิงก์ วิธีย้ายไดเรกทอรีดังกล่าวไปยังพาร์ติชันอื่นปล่อยให้มันอยู่/mnt/Yกับการรักษาฮาร์ดลิงก์เหล่านั้น

เพื่อให้ภาพประกอบดีขึ้นฉันหมายถึงอะไรโดย "ไดเรกทอรีแชร์ไฟล์ร่วมกันกับฮาร์ดลิงก์" นี่คือตัวอย่าง:

# let's create three of directories and files
mkdir -p a/{b,c,d}/{x,y,z}
touch a/{b,c,d}/{x,y,z}/f{1,2,3,4,5}
# and copy it with hardlinks
cp -r -l a hardlinks_of_a

หากต้องการเจาะจงมากขึ้นสมมติว่าขนาดไฟล์ทั้งหมดคือ 10G และแต่ละไฟล์มี 10 ลิงก์ คำถามคือวิธีการย้ายไปยังปลายทางด้วยการใช้ 10G (บางคนอาจพูดเกี่ยวกับการคัดลอกด้วย 100G และจากนั้นใช้การขจัดความซ้ำซ้อน - ไม่ใช่สิ่งที่ฉันถาม)

คำตอบ:


29

คำตอบแรก: วิธี GNU

GNU cp -aคัดลอกโครงสร้างและข้อมูลเมตามากที่สุดซ้ำ ๆ ซ้ำ ๆ เท่าที่จะทำได้ ลิงก์ถาวรระหว่างไฟล์ในไดเรกทอรีต้นทางจะรวมอยู่ในนั้น เพื่อเลือกการเก็บรักษาการเชื่อมโยงอย่างหนักโดยเฉพาะโดยไม่ต้องทั้งหมดคุณสมบัติอื่น ๆ ของการใช้งาน-a--preserve=links

mkdir src
cd src
mkdir -p a/{b,c,d}/{x,y,z}
touch a/{b,c,d}/{x,y,z}/f{1,2,3,4,5}
cp -r -l a hardlinks_of_a
cd ..
cp -a src dst

3
+1 บน tar, -1 สำหรับการใช้อาร์กิวเมนต์ gnu-specific สำหรับ cp
WhyNotHugo

คุณให้สามคำตอบในหนึ่งเดียว คุณแบ่งพวกมันออกเป็นสามกลุ่มเพื่อให้พวกเขาสามารถแสดงความคิดเห็นและประเมินแยกกันได้หรือไม่? (เคล็ดลับ: คุณสามารถแก้ไขได้โดยปล่อยเพียงอันเดียว - เช่น "cp -a" หลังจากนั้นเพิ่มอีกสองรายการสำหรับ "tar" และ "pax")
Grzegorz Wierzowiecki

1
@GrzegorzWierzowiecki แยกสำเร็จ
Alan Curry

6
@Hugo: ไม่มีอะไรผิดปกติกับการใช้ args เฉพาะ GNU กับเครื่องมือมาตรฐาน เวอร์ชัน GNU เป็นมาตรฐานที่ไม่เป็นจริงในทุกวันนี้และแม้ว่าพวกเขาจะไม่ได้ติดตั้งไว้ล่วงหน้ามันเป็นเรื่องธรรมดาที่จะติดตั้งเครื่องมือของ GNU (ฉันรู้ว่าฉันทำมาตลอด - มันดีกว่ารุ่นโซลิสและรุ่น bsd และพวกเขาให้ความสอดคล้องระหว่าง * ต่างกัน) อาจเป็นวิธีปฏิบัติที่ดีในการชี้ให้เห็น GNUisms เมื่อคุณใช้ แต่ไม่จำเป็น นอกจากนี้ Grzegorz ไม่ได้พูดว่า "ไม่ได้อยู่ใน linux" ดังนั้นจึงสมเหตุสมผลที่จะสมมติว่าเป็นสภาพแวดล้อมที่เขาพูดถึง
cas

1
@WhyNotHugo: POSIX เป็นอย่างไร "อาจมีมาตรฐานมากกว่านี้" POSIX เป็นสิ่งที่นำเราไปสู่ที่ที่เราอยู่ คุณรู้หรือไม่ว่า Windows ทุกรุ่นตั้งแต่ Windows NT สอดคล้องกับ POSIX อย่างสมบูรณ์ มีข้อจำกัดความยาวของพา ธ ที่ 255 อักขระเมื่อใช้ฟังก์ชัน POSIX ของไฟล์ I / O ซึ่งจะทำให้ไร้ประโยชน์ คุณรู้หรือไม่ว่า Solaris, Irix, HP-UX เป็นไปตาม POSIX ทั้งหมด แต่ข้อโต้แย้งทั้งหมดของเครื่องมือของพวกเขานั้นแตกต่างกันไป (เช่น tar) cp -a เป็นข้อกำหนดขั้นต่ำสำหรับรุ่น cp ใด ๆ ที่ต้องการแทนที่สำเนา GNU
โยฮันเนสโอเวอร์แมน

36

rsync มี-Hหรือมี--hard-linksตัวเลือกสำหรับสิ่งนี้และมีประโยชน์ตามปกติของ rsync ที่สามารถหยุดและรีสตาร์ทได้และจะถูกเรียกใช้อีกครั้งเพื่อจัดการกับไฟล์ใด ๆ ที่มีการเปลี่ยนแปลงระหว่าง / หลังการรันครั้งก่อนได้อย่างมีประสิทธิภาพ

-H, --hard-links
    This tells rsync to look for hard-linked files in
    the source and link together the corresponding
    files on the destination.  Without  this option,
    hard-linked files in the source are treated as
    though they were separate files. [...]

อ่านrsyncman page และค้นหา -H มีรายละเอียดมากขึ้นเกี่ยวกับคำเตือนเฉพาะ


2
ฉันตรวจสอบแล้ว - ใช้งานได้
Grzegorz Wierzowiecki

ใช่ฉันรู้ ฉันใช้มันเป็นเวลาหลายปีในสคริปต์สำรองของฉัน เพื่อย้ายไฟล์ระหว่างระบบไฟล์เช่นเดียวกับในคำถามของคุณ
cas

rsync ใช้ gobs หน่วยความจำเมื่อสร้างรายการไฟล์ สำหรับฉันหลังจาก "สร้างรายชื่อไฟล์ ... " หลายชั่วโมงมันเต็มไปด้วยหน่วยความจำ 16GB ของฉันและประกันตัวว่าไม่มีการคัดลอกอะไรเลย YMMV
msc

2
จากman rsync: เริ่มต้นด้วย rsync 3.0.0 อัลกอริทึมแบบเรียกซ้ำที่ใช้อยู่ตอนนี้เป็นการสแกนแบบเพิ่มหน่วยความจำที่ใช้หน่วยความจำน้อยกว่าก่อนและเริ่มการถ่ายโอนหลังจากการสแกนไดเรกทอรีสองสามรายการแรกเสร็จสมบูรณ์ การสแกนที่เพิ่มขึ้นนี้มีผลต่ออัลกอริทึมการเรียกซ้ำของเราเท่านั้นและจะไม่เปลี่ยนการถ่ายโอนที่ไม่เกิดซ้ำ เป็นไปได้ก็ต่อเมื่อการถ่ายโอนทั้งสองด้านเป็นเวอร์ชั่น 3.0.0 เป็นอย่างน้อย โปรดทราบว่าทั้งสอง--delete-beforeและ--delete-afterปิดการใช้งานอัลกอริทึมที่ปรับปรุงนี้
cas

นอกจากนี้ในขณะที่rsyncมีประโยชน์อย่างเหลือเชื่อเช่นกันมันไม่ได้เป็นเครื่องมือที่ดีที่สุดสำหรับทุกงาน วันนี้ฉันชอบที่จะใช้ชุดข้อมูล ZFS เพื่อให้ฉันสามารถจับภาพและzfs sendพวกเขา - ฉันส่วนใหญ่ใช้ rsync ในระบบไฟล์ที่ไม่ใช่ ZFS btrfsมีความสามารถในการจับภาพ + ส่งที่คล้ายกัน
cas

14

คำตอบที่สาม: วิธี POSIX

POSIX ไม่ได้สร้างมาตรฐานtarยูทิลิตี้แม้ว่าพวกเขาจะได้มาตรฐานtarรูปแบบการเก็บถาวร ยูทิลิตี้ POSIX สำหรับจัดการกับไฟล์เก็บถาวร tar นั้นถูกเรียกใช้paxและมีคุณสมบัติโบนัสที่สามารถทำการดำเนินการ pack และ unpack ในกระบวนการเดียว

mkdir dst
pax -rw src dst

10

คำตอบที่สอง: วิธี UNIX โบราณ

สร้างไฟล์เก็บถาวร tar ในไดเร็กทอรีต้นทางส่งไปที่ไปป์และคลายไฟล์ในไดเร็กทอรีปลายทาง

# create src as before
(cd src;tar cf - .) | (mkdir dst;cd dst;tar xf -)

1
ตรวจสอบ -> ทำงาน การเก็บรักษาลิงก์ถาวร
Grzegorz Wierzowiecki

1
ความเห็นใด ๆ ว่าทำไมสิ่งนี้ถึงรักษาลิงก์ถาวรไว้
peterph

1
เพราะtarเก็บลิงค์ยาก อย่างน้อยใน GNU tar คุณสามารถปิดใช้งานพฤติกรรมนี้ได้ด้วย--hard-dereference
cas

ในกรณีของฉันพยายามที่จะคัดลอกลำดับชั้นไดเรกทอรีขนาดใหญ่ (การสำรองข้อมูล TimeMachine), tar เก็บรักษาลิงก์ถาวรบางอย่าง แต่ทำซ้ำไฟล์ในบางกรณี ผมคิดว่านี่เป็นเพราะไม่ได้มีรายชื่อไฟล์เต็มรูปแบบเป็นไฟล์ยังคงถูกประปามาจากtar x tar cอาจเป็นไปได้ว่าถ้าคุณบันทึกที่เก็บถาวรทั้งหมดก่อนที่จะแตกมันจะไม่เป็นไร ฉันจะมีความสุขมากถ้ามีคนยืนยันทฤษฎีนี้
msc

10

ที่มา: http://www.cyberciti.biz/faq/linux-unix-apple-osx-bsd-rsync-copy-hard-links/

สิ่งที่คุณต้องทำสำเนาที่แน่นอนคือ

rsync -az -H --delete --numeric-ids /path/to/source/ /path/to/dest/

ดูความคิดเห็นของฉันเกี่ยวกับ rsync ข้างต้น
msc

1
ฉันสงสัยว่าสิ่งนี้จะไม่คัดลอก ACLs แอตทริบิวต์เพิ่มเติมและอื่น ๆ รุ่น Linux ยังมีตัวเลือก -A และ -X เพื่อรักษาสิ่งเหล่านี้ แต่ฉันคิดว่าคุณโชคไม่ดีที่ MacOS
Edward Falk
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.