ฉันจะใช้ rsync เพื่อทำซ้ำแผนผังไดเรกทอรีสร้างการเชื่อมโยงไปยังไฟล์ได้อย่างไร


23

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

อย่างไรก็ตามฉันไม่สามารถรับ rsync ได้ ฉันเหนื่อย

rsync -a --link-dest=$DATA $DATA $DATA/../upgrade_tmp

แต่แทนที่จะสร้างฮาร์ดลิงก์ไปยังไฟล์ rsync ก็อปปี้ไฟล์ทั้งหมด มีปัญหาในการใช้ซอร์สเดียวกันกับไดเร็กทอรี link-dest หรือไม่?

คำตอบ:


21

rsync เป็นเครื่องมือที่ทรงพลัง แต่โชคไม่ดีที่จู้จี้จุกจิกเกี่ยวกับชื่อพา ธ ของมัน

ถ้า$DATAเป็นพา ธ สัมบูรณ์ (เช่นเริ่มต้นด้วย/) ดังนั้นบรรทัดคำสั่งที่ถูกต้องที่จะใช้คือ:

rsync -a --link-dest=$DATA $DATA/ $DATA/../upgrade_tmp

[เพียงสั้น ๆ เกี่ยวกับrsyncความไม่ชอบมาพากลของ บันทึกส่วนท้ายที่/เพิ่มให้กับอาร์กิวเมนต์แหล่งที่มา สิ่งนี้บอกrsyncให้ทำงานกับเนื้อหาของซอร์สไดเร็กทอรีแทนที่จะใช้กับซอร์สไดเร็กทอรีเอง (ฉันสมมติ$DATAว่าไม่ได้มีส่วนท้าย/อยู่) ในกรณีนี้เราต้องการทำงานกับเนื้อหาดังนั้นเราจึงเพิ่มส่วนท้าย/]

หากในอีกทาง$DATAหนึ่งเป็นเส้นทางสัมพัทธ์ (เช่นมันไม่ได้เริ่มต้นด้วย/) แล้วความคิดเห็นของ Sean R เกี่ยวกับ--link-destis bang on: เส้นทาง link-dest ถูกตีความสัมพันธ์กับเส้นทางปลายทางดังนั้นคุณจะใช้ต่อไปนี้:

rsync -a --link-dest=../`basename $DATA` $DATA/ $DATA/../upgrade_tmp

แก้ไข

หมายเหตุสุดท้ายสุดท้ายปรากฎว่าrsyncบรรทัดคำสั่งที่สองที่ฉันให้ควรทำงานโดยไม่คำนึงว่า$DATAเป็นเส้นทางที่สมบูรณ์หรือbasenameไม่เนื่องจากไม่สนใจว่าเส้นทางเป็นแบบสัมบูรณ์หรือแบบสัมพัทธ์


1
เพียงแค่ฟันที่หายไปใครจะนึกถึงสิ่งนั้น…ขอบคุณสำหรับคำอธิบายที่ดี!
Jean-Philippe Pellet

ขอบคุณสำหรับสิ่งนี้ฉันได้ลองทำตามคำแนะนำในการสำรองข้อมูลเพิ่มเติมหลายอย่างเช่นนี้และไม่พบการเอ่ยถึงเรื่องการเล่นโวหารนี้ นี่เป็นเพียงสิ่งเดียวที่ทำให้มั่นใจได้ว่าไฟล์ต่าง ๆ ถูกเชื่อมโยงกันอย่างถาวร การตรวจสอบว่าจำนวนการอ้างอิงคือ> 1 และหมายเลข inode เหมือนกันกับls -ilah
Walf

ฉันใช้สิ่งนี้ร่วมกับฟังก์ชั่น relpath () ที่อธิบายไว้ที่unix.stackexchange.com/a/85068/57414เพื่อสำรองข้อมูล$SOURCEไดเรกทอรีเป็น$TARGETdir ดังนี้:SOURCE='abs_path_to_backup'; TARGET='.'; rsync -a --link-dest=$(relpath $TARGET $SOURCE) $SOURCE/ $TARGET/
Nathan S. Watson-Haigh

13

สิ่งที่คุณต้องการคือ "cp -al":

cp -al $DATA/ $DATA/../upgrade_tmp/
  • - เกิดขึ้นซ้ำ ๆ เช่น rsync -a
  • -l จะฮาร์ดลิงก์ไฟล์แทนการคัดลอก

1
cp -alไม่สามารถใช้กับระบบของฉันได้ (Mac OS X 10.6) ฉันจะใช้สันติภาพแทน ...
Jean-Philippe Pellet

7

--link-destตัวเลือกในการrsyncเป็นญาติกับปลายทางไดเรกทอรีไม่ไดเรกทอรีปัจจุบัน ดังนั้นสิ่งที่คุณต้องการคือ:

rsync -a --link-dest=../`basename $DATA` $DATA $DATA/../upgrade_tmp

โอ๊ะฉันหมายถึงชื่อเดิม แต่เดิมฉันมีชื่อเล่น
Sean Reifschneider

1
หน้าคนบอกว่า--link-destตัวเลือกนั้นถ้าสัมพันธ์จะเกี่ยวข้องกับไดเรกทอรีเป้าหมาย ในกรณีของฉันมันแน่นอน แม้การทำให้สัมพันธ์กับไดเรกทอรีเป้าหมายไม่ได้ทำให้งานนี้
Jean-Philippe Pellet

7

กลับกลายเป็นว่ามันยากกว่าที่จะทำเช่นนี้กับrsyncเครื่องมืออื่น ๆ คำตอบที่ถูกต้องสำหรับคำว่าrsyncSteven Monai แต่วิธีที่ง่ายที่สุดในการทำเช่นนี้คือการใช้อย่างใดอย่างหนึ่งcp -alหรือpax -rwlในระบบที่-lไม่มีตัวเลือกที่ถูกต้องสำหรับcp:

pax -rwl $DATA $DATA/../upgrade_tmp

หรือ

cp -al $DATA/ $DATA/../upgrade_tmp/

4

มันเหมาะกับฉัน:

$ rsync --hard-links --recursive --link-dest=/local user@host:/remote/ /local

ฉันใช้ rsync เวอร์ชั่น 3.1.0

จากมนุษย์ :

--hard การเชื่อมโยง

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

--link-ปลายทาง = DIR

ไฟล์ที่ไม่มีการเปลี่ยนแปลงนั้นมีการเชื่อมโยงอย่างหนักจาก DIR ไปยังไดเรกทอรีปลายทาง ไฟล์จะต้องเหมือนกันในแอตทริบิวต์ที่สงวนไว้ทั้งหมด (เช่นสิทธิ์อาจเป็นเจ้าของ) เพื่อให้ไฟล์เชื่อมโยงเข้าด้วยกัน


2
มีข้อมูลโค้ดเพียงอย่างเดียวไม่เพียงพออธิบายว่ามันทำอะไรและทำไม
peterh กล่าวว่าคืนสถานะโมนิก้า

-ฮาร์ดลิงก์บอก rsync เพื่อค้นหาไฟล์ที่เชื่อมโยงอย่างหนักในการถ่ายโอนโดยไม่มีตัวเลือกนี้ไฟล์ที่เชื่อมโยงอย่างหนักในการถ่ายโอนจะได้รับการปฏิบัติเสมือนเป็นไฟล์แยกต่างหาก --link-dest = DIRไฟล์ที่ไม่มีการเปลี่ยนแปลงมีการเชื่อมโยงอย่างหนักจาก DIR ไปยังไดเรกทอรีปลายทาง ไฟล์จะต้องเหมือนกันในแอตทริบิวต์ที่สงวนไว้ทั้งหมด (เช่นสิทธิ์อาจเป็นเจ้าของ) เพื่อให้ไฟล์เชื่อมโยงเข้าด้วยกัน
Alexander Fedorov

1
ยอดเยี่ยม ขอขอบคุณ. ที่จริงแล้วฉันพบคำตอบของคุณในคิว "คุณภาพต่ำ" หมายความว่ามีการลงคะแนนหากคำตอบของคุณควรถูกลบหรือไม่ แต่ไม่เพียง แต่อันตรายของการลบเท่านั้นคือเหตุผลที่พยายามให้คำตอบที่มีรูปแบบที่ดีคำตอบที่ "มนุษย์" แต่มันก็ช่วยได้มากเช่นกันหากคุณต้องการรวบรวม upvotes
peterh กล่าวว่าคืนสถานะโมนิก้า

2

สามารถลองลิงค์ต่อไปนี้http://www.lessfs.com/wordpress/มันทำงานบนCOW (คัดลอกเมื่อเขียน) ที่จะช่วยประหยัดเวลาและพื้นที่


Lessfs เป็นที่น่าสนใจมาก แต่ก็มีการทดลองมาก ยังไม่แนะนำสำหรับการใช้งานจริง
mattdm

2

ขั้นแรกให้สร้างไดเรกทอรีบนปลายทางเท่านั้น:

rsync -av --include '*/' --exclude '*' /source/ /destination/

จากนั้นฮาร์ดลิงก์ไฟล์เท่านั้น:

cd /source
find . -type f -exec ln -v {} /destination/{} \;

ขอบคุณ - จริง ๆ แล้วฉันอาจใช้paxตามที่แสดงในความคิดเห็นของฉันด้านบนซึ่งดูง่ายขึ้น
Jean-Philippe Pellet

1

ใช้ตัวเลือก -H เพื่อเก็บรักษาลิงก์ถาวรและอ่าน manpage


1
-H ไม่ทำงาน ฉันไม่มีฮาร์ดลิงก์ที่จะเก็บไว้ในแผนผังต้นไม้ฉันต้องการเพียงแค่สำเนาต้นไม้ต้นกำเนิดของฉันซึ่งในสำเนาไฟล์ทั้งหมดจะถูกลิงก์ไปยังไฟล์ต้นฉบับ ขออภัยในคำถามเดิมของฉันไม่ชัดเจน…
Jean-Philippe Pellet

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