ฉันได้คัดลอกเทราไบต์ของไฟล์ด้วยrsyncแต่ฉันลืมที่จะใช้--archiveเพื่อรักษาคุณสมบัติพิเศษของไฟล์
ฉันพยายามดำเนินการrsyncอีกครั้งคราวนี้ด้วย--archiveแต่มันช้ากว่าที่ฉันคาดไว้ มีวิธีง่าย ๆ ที่จะทำเร็วขึ้นโดยเพียงแค่คัดลอกเมตาดาต้าซ้ำ?
ฉันได้คัดลอกเทราไบต์ของไฟล์ด้วยrsyncแต่ฉันลืมที่จะใช้--archiveเพื่อรักษาคุณสมบัติพิเศษของไฟล์
ฉันพยายามดำเนินการrsyncอีกครั้งคราวนี้ด้วย--archiveแต่มันช้ากว่าที่ฉันคาดไว้ มีวิธีง่าย ๆ ที่จะทำเร็วขึ้นโดยเพียงแค่คัดลอกเมตาดาต้าซ้ำ?
คำตอบ:
ตกลงคุณสามารถคัดลอกเจ้าของกลุ่มได้รับอนุญาตและการประทับเวลาโดยใช้--referenceพารามิเตอร์chown, ,chmod touchนี่คือสคริปต์ที่ต้องทำ
#!/bin/bash
# Filename: cp-metadata
myecho=echo
src_path="$1"
dst_path="$2"
find "$src_path" |
while read src_file; do
dst_file="$dst_path${src_file#$src_path}"
$myecho chmod --reference="$src_file" "$dst_file"
$myecho chown --reference="$src_file" "$dst_file"
$myecho touch --reference="$src_file" "$dst_file"
done
คุณควรรันด้วยsudo(เพื่ออนุญาตให้ chown) และมีสองพารามิเตอร์: ไดเรกทอรีต้นทางและปลายทาง สคริปต์สะท้อนสิ่งที่มันจะทำเท่านั้น หากมีความพึงพอใจการเปลี่ยนแปลงบรรทัดด้วยmyecho=echomyecho=
touch --reference=otherfile fileการที่คุณสามารถใช้ อัปเดตคำตอบ
touchโดยการออกแบบจะเปลี่ยนเฉพาะเวลาการแก้ไขและการเข้าถึงเท่านั้นเวลา "การสร้าง" จะไม่ได้รับผลกระทบ (ฉันคิดว่า ext2 / 3 ไม่สนับสนุนการเปลี่ยนเวลา แต่มันอาจสำคัญว่าคุณใช้ NTFS หรือไม่ชอบ)
-cสลับไปที่คำสั่งที่จะหยุดมันสร้างไฟล์ที่ว่างเปล่าในtouch $dst_path
คำเตือน: หากไม่มีวิธีแก้ปัญหาพิเศษ GNU cp --attributes-onlyจะตัดทอนไฟล์ปลายทางอย่างน้อยที่สุดใน Precise ดูการแก้ไขด้านล่าง
เดิม:
ในสถานการณ์นี้คุณอาจต้องการ--attributes-onlyตัวเลือกของ GNU cp ร่วมกับ--archiveซึ่งเป็นรหัสที่ได้ลองและทดสอบแล้วจะทำทุกอย่างที่ไม่เชื่อเรื่องระบบแฟ้มและไม่ทำตาม symlinks (ทำตามได้ไม่ดี!):
cp --archive --attributes-only /source/of/failed/backup/. /destination/
เช่นเดียวกับไฟล์cpเป็นสารเติมแต่งที่มีแอตทริบิวต์เพิ่มเติม: หากทั้งต้นทางและปลายทางมีแอตทริบิวต์ที่ขยายเพิ่มมันจะเพิ่มแอตทริบิวต์เพิ่มเติมของต้นทางไปยังปลายทาง (แทนที่จะลบ xattrs ทั้งหมดของปลายทางก่อน) แม้ว่าสิ่งนี้จะสะท้อนcpพฤติกรรมอย่างไรถ้าคุณคัดลอกไฟล์ลงในแผนผังที่มีอยู่ แต่อาจไม่ใช่สิ่งที่คุณคาดหวัง
นอกจากนี้โปรดทราบว่าหากคุณไม่ได้เก็บลิงก์ถาวรไว้ในครั้งแรกด้วยrsyncแต่ต้องการที่จะเก็บลิงก์ไว้ตอนนี้คุณcp จะไม่แก้ไขปัญหานั้นให้คุณ คุณน่าจะดีที่สุดเมื่อใช้rsyncตัวเลือกที่เหมาะสม (ดูคำตอบอื่น ๆของฉัน) และอดทน
หากคุณพบคำถามนี้ในขณะที่ต้องการแยกเนื้อหาเมตาดาต้า / ไฟล์ที่รวมกันใหม่โดยเจตนาแล้วคุณอาจต้องการดูmetastoreซึ่งอยู่ในที่เก็บของ Ubuntu
ที่มา: คู่มือ GNU coreutils
แก้ไขเพื่อเพิ่ม:
cpจาก GNU coreutils> = 8.17 ขึ้นไปจะทำงานตามที่อธิบายไว้ แต่ coreutils <= 8.16 จะตัดทอนไฟล์เมื่อเรียกคืนข้อมูลเมตา หากมีข้อสงสัยอย่าใช้cpในสถานการณ์นี้ ใช้rsyncกับตัวเลือกที่ถูกต้องและ / หรืออดทน
ฉันจะไม่แนะนำสิ่งนี้เว้นแต่คุณจะเข้าใจอย่างถ่องแท้ว่าคุณกำลังทำอะไร แต่ GNU ก่อนหน้านี้cpสามารถป้องกันการตัดทอนไฟล์โดยใช้เคล็ดลับ LD_PRELOAD :
/*
* File: no_trunc.c
* Author: D.J. Capelis with minor changes by Zak Wilcox
*
* Compile:
* gcc -fPIC -c -o no_trunc.o no_trunc.c
* gcc -shared -o no_trunc.so no_trunc.o -ldl
*
* Use:
* LD_PRELOAD="./no_trunc.so" cp --archive --attributes-only <src...> <dest>
*/
#define _GNU_SOURCE
#include <dlfcn.h>
#define _FCNTL_H
#include <bits/fcntl.h>
extern int errorno;
int (*_open)(const char *pathname, int flags, ...);
int (*_open64)(const char *pathname, int flags, ...);
int open(const char *pathname, int flags, mode_t mode) {
_open = (int (*)(const char *pathname, int flags, ...)) dlsym(RTLD_NEXT, "open");
flags &= ~(O_TRUNC);
return _open(pathname, flags, mode);
}
int open64(const char *pathname, int flags, mode_t mode) {
_open64 = (int (*)(const char *pathname, int flags, ...)) dlsym(RTLD_NEXT, "open64");
flags &= ~(O_TRUNC);
return _open64(pathname, flags, mode);
}
errornoควรจะerrnoใช่มั้ย
rsyncพร้อมกับตัวเลือกที่เหมาะสมเป็นคำตอบสำหรับคำถามอื่น ...
การตอบคำถามเป็น "rsync มีเมทาดาทาที่จะคัดลอกเท่านั้นเหตุใดจึงช้าและฉันจะทำให้เร็วขึ้นได้อย่างไร":
rsyncมักจะใช้ mtimes เท่ากันเป็นฮิวริสติกในการตรวจจับและข้ามไฟล์ที่ไม่เปลี่ยนแปลง โดยไม่ต้อง--archive(โดยเฉพาะโดยไม่ต้อง--times) mtimes ของไฟล์ปลายทางจะถูกตั้งค่าเป็นเวลาที่คุณ rsync-ed ในขณะที่ mtimes ของไฟล์ต้นฉบับจะยังคงอยู่ (ไม่สนใจคุณด้วยตนเอง) หากไม่มีการรับรองจากภายนอกว่าเนื้อหาของไฟล์ต้นฉบับนั้นไม่มีการเปลี่ยนแปลง rsync จะต้องถือว่าพวกเขามีและดังนั้นจึงต้องทำการตรวจสอบพวกเขาและ / หรือคัดลอกไปยังปลายทางอีกครั้ง สิ่งนี้บวกกับความจริงที่บอก--whole-fileเป็นนัยสำหรับ local-> local syncs ทำให้rsyncโดยไม่--timesเทียบเท่ากับcpการซิงค์ในท้องถิ่น
โดยมีเงื่อนไขว่าการอัปเดตเนื้อหาของไฟล์ปลายทางนั้นเป็นที่ยอมรับหรือหากไฟล์ต้นฉบับนั้นไม่ถูกแตะต้องตั้งแต่การคัดลอกต้นฉบับคุณควรพบว่าrsync --archive --size-onlyเร็วกว่า rsync ที่ไร้เดียงสา
หากมีข้อสงสัยเกี่ยวกับสิ่งที่rsyncคัดลอกซึ่งใช้เวลานานมากให้rsync --archive --dry-run --itemize-changes ...บอกรายละเอียดที่ละเอียดถี่ถ้วน
ในการถ่ายโอนโลคัลเมื่อแหล่งที่มาและปลายทางอยู่บนระบบไฟล์ที่เมาท์แบบโลคัลrsyncจะคัดลอกเนื้อหาไฟล์ทั้งหมด เพื่อหลีกเลี่ยงปัญหานี้คุณสามารถใช้
rsync -a --no-whole-file source dest
rsyncไม่ให้ใช้ทางลัดเมื่อไฟล์ต่าง ๆ อยู่ในโลคัลพา ธ แต่ไม่ได้ป้องกันrsyncการคัดลอกเนื้อหา
ฉันต้องทำสิ่งนี้จากระยะไกลไปยังคอมพิวเตอร์เครื่องอื่นดังนั้นฉันจึงไม่สามารถใช้ - การอ้างอิง
ฉันใช้สิ่งนี้เพื่อสร้างสคริปต์ ...
find -printf "touch -d \"%Tc\" \"%P\"\n" >/tmp/touch.sh
แต่ให้แน่ใจว่าไม่มีชื่อไฟล์ใด ๆ "ในพวกเขาก่อน ...
find | grep '"'
จากนั้นคัดลอก touch.sh ไปยังคอมพิวเตอร์ระยะไกลของคุณแล้วเรียกใช้ ...
cd <DestinationFolder>; sh /tmp/touch.sh
นอกจากนี้ยังมีตัวเลือกในการค้นหา -printf เพื่อพิมพ์ผู้ใช้ชื่อกลุ่มหากคุณต้องการคัดลอก
findการสร้างสคริปต์กล่าวว่าการใช้ ผมอยู่ในสถานการณ์เดียวกัน - ลืมที่จะคัดลอกคุณลักษณะต้นทางและปลายทางดิสก์มีอยู่แล้วในเครื่องที่แตกต่างและไม่ได้จริงๆต้องการกลับว่า