วิธีที่ดีที่สุดในการซิงค์ไฟล์ - คัดลอกเฉพาะไฟล์ที่มีอยู่และเฉพาะในกรณีที่ใหม่กว่าเป้าหมาย


18

ฉันทำข้อมูลนี้ให้ตรงกับบน Ubuntu 12.04 ไฟล์โดยทั่วไปคือไฟล์ข้อความขนาดเล็ก (รหัส)

ฉันต้องการที่จะคัดลอก (รักษาแสตมป์ mtime) จากsourceไดเรกทอรีไปtargetแต่ฉันเพียงต้องการที่จะคัดลอกไฟล์ถ้าในtarget ที่มีอยู่แล้วและเป็นที่เก่าsourceกว่าหนึ่งใน

ดังนั้นฉันจึงคัดลอกไฟล์ที่ใหม่กว่าsourceเท่านั้น แต่ต้องมีอยู่targetไม่เช่นนั้นจะไม่ถูกคัดลอก ( sourceจะมีไฟล์มากกว่าtargetนั้น)

ฉันจะคัดลอกจากจริงsourceไปยังหลายtargetไดเรกทอรี ฉันพูดถึงเรื่องนี้ในกรณีที่มีผลกระทบต่อการเลือกวิธี อย่างไรก็ตามฉันสามารถเรียกใช้คำสั่งของฉันได้อย่างง่ายดายหลายครั้งโดยระบุใหม่targetทุกครั้งหากเป็นสิ่งที่จำเป็น

คำตอบ:


29

ฉันเชื่อว่าคุณสามารถใช้rsyncในการทำเช่นนี้ การตรวจสอบที่สำคัญจำเป็นต้องใช้--existingและ--updateสวิตช์

        --existing              skip creating new files on receiver
        -u, --update            skip files that are newer on the receiver

คำสั่งเช่นนี้จะทำ:

$ rsync -avz --update --existing src/ dst

ตัวอย่าง

สมมติว่าเรามีข้อมูลตัวอย่างต่อไปนี้

$ mkdir -p src/; touch src/file{1..3}
$ mkdir -p dst/; touch dst/file{2..3}
$ touch -d 20120101 src/file2

ซึ่งมีลักษณะดังนี้:

$ ls -l src/ dst/
dst/:
total 0
-rw-rw-r--. 1 saml saml 0 Feb 27 01:00 file2
-rw-rw-r--. 1 saml saml 0 Feb 27 01:00 file3

src/:
total 0
-rw-rw-r--. 1 saml saml 0 Feb 27 01:00 file1
-rw-rw-r--. 1 saml saml 0 Jan  1  2012 file2
-rw-rw-r--. 1 saml saml 0 Feb 27 01:00 file3

ตอนนี้ถ้าฉันจะซิงค์ไดเรกทอรีเหล่านี้จะไม่มีอะไรเกิดขึ้น:

$ rsync -avz --update --existing src/ dst
sending incremental file list

sent 12 bytes  received 31 bytes  406.00 bytes/sec
total size is 0  speedup is 0.00

หากเราtouchเป็นไฟล์ต้นฉบับเพื่อให้ใหม่กว่า:

$ touch src/file3 
$ ls -l src/file3
-rw-rw-r--. 1 saml saml 0 Feb 27 01:04 src/file3

การรันrsyncคำสั่งอื่น:

$ rsync -avz --update --existing src/ dst
sending incremental file list
file3

sent 115 bytes  received 31 bytes  292.00 bytes/sec
total size is 0  speedup is 0.00

เราเห็นได้ว่าfile3มันใหม่กว่าและมีอยู่ในdst/นั้นมันจึงถูกส่ง

การทดสอบ

เพื่อให้แน่ใจว่าสิ่งต่าง ๆ ทำงานก่อนที่คุณจะตัดคำสั่งให้หลวมฉันขอแนะนำให้ใช้rsyncสวิตช์ตัว--dry-runอื่น ลองเพิ่มอีกอัน-vด้วยrsyncผลลัพธ์ที่ได้จะละเอียดยิ่งขึ้น

$ rsync -avvz --dry-run --update --existing src/ dst 
sending incremental file list
delta-transmission disabled for local transfer or --whole-file
file1
file2 is uptodate
file3 is newer
total: matches=0  hash_hits=0  false_alarms=0 data=0

sent 88 bytes  received 21 bytes  218.00 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)

ขอขอบคุณ. ฉันไม่ต้องการตัวเลือก rsync เพิ่มเติมอีกหรือไม่ ฉันกำลังอ่าน man page rsync --archive --update --existing --whole-file --itemize-changes a/ bดูเหมือนว่าฉันอาจจะต้องนี้: หรือตัวเลือกเหล่านั้นส่วนใหญ่ไม่จำเป็น? (ฉันเพิ่มทั้งไฟล์เพราะส่วนใหญ่เป็นไฟล์ข้อความขนาดเล็ก)
MountainX สำหรับ Monica Cellio

@MountainX - เพิ่มตัวเลือกที่คุณต้องการเท่านั้น ฉันจะเริ่มต้นด้วย-aสวิตช์ที่ยอดเยี่ยม, -rlptgoD.
slm

ผมขอชี้แจงว่า ฉันสับสนเกี่ยวกับและ--update --existingฉันต้องการทั้งคู่หรือไม่ ผมทดสอบวิธีการแก้ปัญหาของคุณและมันดูเหมือนว่าจะทำงาน --updateแต่ฉันยังคงรู้สึกปลอดภัยมากขึ้นเพิ่ม
MountainX สำหรับ Monica Cellio

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