scp โดยไม่ต้องแทนที่ไฟล์ที่มีอยู่ในปลายทาง


158

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


ใช่มันเป็นที่น่ารำคาญเมื่อโปรแกรมที่มีประโยชน์ / ยูทิลิตี้ไม่ได้ที่หนึ่ง "ถ้าเพียง แต่มันอาจจะ ..." ตัวเลือก! ในกรณีนี้ "--noclobber"!
MikeW

คำตอบ:


139

ใช้rsyncและผ่าน-uหากคุณต้องการอัปเดตเฉพาะไฟล์ที่ใหม่กว่าในไดเรกทอรีดั้งเดิมหรือ--ignore-existingข้ามไฟล์ทั้งหมดที่มีอยู่แล้วในปลายทาง

rsync -au /local/directory/ host:/remote/directory/
rsync -a --ignore-existing /local/directory/ host:/remote/directory/

(สังเกต/ด้านที่มา: โดยไม่rsyncสร้าง/remote/directory/directoryขึ้น)


@ ทันใดนั้นฉันไม่เข้าใจความคิดเห็นของคุณและฉันไม่เห็นคำตอบหรือแสดงความคิดเห็นโดยจันทรา --ignore-existingเพิ่มโดยไม่มีการแทนที่คุณเห็นข้อมูลสูญหายอะไร
Gilles

ขออภัยฉันดูเฉพาะตัวอย่างแรกของคุณที่คุณสามารถมีการสูญเสียข้อมูล (และ IMHO ไม่ใช่สิ่งที่ OP ขอ) หากคุณรวม - การสูญเสียข้อมูลที่มีอยู่เดิมไม่ควรเกิดขึ้น
Anthon

สิ่งนี้ไม่ได้ช่วยหากระบบระยะไกลไม่rsyncสามารถใช้งานได้อย่างง่ายดาย .... (เช่น Win32-OpenSSH)
Gert van den Berg

@GertvandenBerg rsync ค่อนข้างง่ายในการติดตั้งบน Windows ไม่ยากกว่า SSH
Gilles

@Gilles: จริง แต่ตัวเลือกทั้งหมดดูเหมือนว่าจะเกี่ยวข้องกับ Cygwin DLLs ... (สถานะปัจจุบันของพอร์ต MS ของ OpenSSH เป็นเช่นนั้นที่ทำให้การบีบอัดบน SCP นั้นเพียงพอที่จะทำลาย SCP ... ) (รับ rsync ทำงานบน Win32 -OpenSSH ดูเหมือนว่าไม่สำคัญ - หวังว่าจะปรับปรุงได้ตลอดเวลา) (Solaris 10 เป็นอีกตัวอย่างหนึ่งซึ่งเป็นแพ็คเกจของบุคคลที่สามและ--rsync-pathจำเป็นต้องใช้)
Gert van den Berg

82

scpจะเขียนทับไฟล์หากคุณมีสิทธิ์ในการเขียนลงไป

กล่าวอีกนัยหนึ่ง: คุณสามารถscpข้ามไฟล์ดังกล่าวได้อย่างมีประสิทธิภาพโดยลบสิทธิ์การเขียนไว้ชั่วคราว (ถ้าคุณเป็นเจ้าของไฟล์นั่นคือ)


5
ขอบคุณสำหรับสิ่งนี้. เป็นเคล็ดลับที่ฉันต้องการ
saccharine

ตรวจสอบให้แน่ใจว่าคุณคัดลอกไฟล์กลับมาที่คุณเพิ่ม * เพื่อทำ ตัวอย่างscp -r user@server.com:/location/of/files/* /local/location/
ริ

1
หา -type f -exec chown root: root {} \;
ลิง

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

เมื่อต้องการทำสิ่งนี้บน windows ให้เลือกไฟล์ทั้งหมดคลิกขวา -> properties -> read only
BenJammin

12

คุณสามารถคัดลอกเฉพาะไฟล์ใหม่ตามวันที่ ใช้find

scp  `find /data/*.gz -type f -mtime +7` USER@SERVER:/backup/

+7 หมายถึงอะไร
ฟรานซิสคิม

@FrancisKim หมายถึงแก้ไขเมื่อ 7 วันที่แล้ว ดังนั้นคำค้นหานี้เลือกไฟล์ * .gz ที่แก้ไขภายใน 7 วันที่ผ่านมา
Vadim Eremeev

4
ไม่ได้ +7 แปลว่ามากกว่า 7 วันที่ผ่านมาจริงเหรอ?
เจฟฟ์เอช.

1
ใช่มันหมายถึง "มากกว่า 7 วันที่ผ่านมา" ไม่มีความคิดที่สนับสนุนสิ่งนี้
Stefan Reich

9

หากคุณสามารถทำให้เนื้อหาไฟล์ปลายทางเป็นแบบอ่านอย่างเดียว:

find . -type f -exec chmod a-w '{}' \;

ก่อนที่จะทำงานscp(มันจะบ่นและข้ามไฟล์ที่มีอยู่)

และเปลี่ยนพวกเขากลับมาหลังจากนั้น ( chmod +wเพื่อรับค่า umask ตาม) หากไฟล์ไม่ได้มีสิทธิ์เขียนตาม umask ของคุณคุณจะต้องจัดเก็บสิทธิ์เพื่อให้คุณสามารถเรียกคืนได้

(คำตอบของ Gilles จะเขียนทับไฟล์ที่มีอยู่หากไฟล์ในเครื่องเป็นไฟล์ใหม่ฉันจะสูญเสียข้อมูลที่มีค่าในแบบนั้นอย่าเข้าใจว่าทำไมคำตอบที่ไม่ถูกต้องและเป็นอันตรายมีคะแนนมากกว่านี้)


2
ฉันไม่เข้าใจ: rsync --ignore-existingคุณทำให้ข้อมูลสูญหายได้อย่างไร
Gilles

4
ผมได้รับข้อผิดพลาดใช้คำสั่งนี้และแทนที่จะมีการใช้:find: missing argument to '-exec' find . -type f -exec chmod a-w {} \;linux ของฉันไม่ดี ymmv
wpearse

นี่เป็นคำตอบที่ดีกว่าและปลอดภัยกว่า คำสั่งที่ถูกต้องในการเปลี่ยนการอนุญาตเป็น @wpearse พูดถึง:find . -type f -exec chmod a-w {} \;
อาเมียร์

6

ผมมีงานที่คล้ายกันในกรณีของฉันฉันไม่สามารถใช้rsync, csyncหรือ FUSE เพราะการจัดเก็บข้อมูลของฉันมีเพียง SFTP rsyncไม่สามารถเปลี่ยนวันที่และเวลาสำหรับไฟล์ได้ยูทิลิตี้อื่น ๆ (เช่นcsync) แสดงข้อผิดพลาดอื่น ๆ ให้ฉัน: " ไม่สามารถสร้างไฟล์ชั่วคราวตรวจพบการเอียงของนาฬิกา "

หากคุณสามารถเข้าถึงเซิร์ฟเวอร์จัดเก็บข้อมูล - เพียงแค่ติดตั้งopenssh-serverหรือเปิดใช้งานrsyncเป็น daemon ที่นี่

ในกรณีของฉัน - ฉันไม่สามารถทำเช่นนี้และการแก้ปัญหาคือ: lftp lftpการใช้งานสำหรับการทำข้อมูลให้ตรงกันด้านล่าง:

lftp -c "open -u login,password sftp://sft.domain.tld/; \
    mirror -c --verbose=9 -e -R -L /srs/folder /rem/folder"

/src/folder- เป็นโฟลเดอร์บนคอมพิวเตอร์ของฉัน/rem/folder- sftp://sft.domain.tld/rem/folderถูก

คุณสามารถค้นหา man pages ได้ตามลิงค์: http://lftp.yar.ru/lftp-man.html


6

หากต้องการคัดลอกทั้งกลุ่มไฟล์มันจะเร็วกว่าที่จะทิ้งไว้ โดยการใช้ -k คุณยังป้องกัน tar จากการเขียนทับไฟล์เมื่อแกะมันออกจากระบบเป้าหมาย

tar -c <source-dir> | ssh <name>@<host> 'tar -kxzf - -C <target-dir>' 

1
มันทำให้การเชื่อมต่อระยะไกล ขั้นแรกให้ tar เป็นแหล่งที่มา, ส่งไปยังการเชื่อมต่อ ssh และคลายออกบนระบบรีโมต
huembi

-1

scpเขียนทับไฟล์และไม่มีสวิตช์หยุดการทำเช่นนั้น แต่คุณสามารถคัดลอกสิ่งต่าง ๆ ออกไปทำ scp แล้วคัดลอกไฟล์ที่มีอยู่กลับมา ตัวอย่าง:

  1. คัดลอกไฟล์ที่มีอยู่ทั้งหมดออกไป

    mkdir original_files ; cp -r * original_files/
    
  2. คัดลอกทุกอย่างโดยใช้ scp

    scp -r user@server:dir/* ./
    
  3. คัดลอกไฟล์ต้นฉบับไปยังสิ่งที่ scp เขียนทับ:

    cp -r original_files/* ./
    

3
วิธีนี้ไม่ได้ช่วยเมื่อคุณพยายามดึงไฟล์จากระยะไกลและรับที่ที่คุณค้าง คือถ้าวัตถุประสงค์ทั้งหมดคือการประหยัดเวลา
Oliver Williams

-1

อีกวิธีหนึ่งในการบรรลุเป้าหมายนี้คือการทำlsในโฟลเดอร์ปลายทาง:

ในโฟลเดอร์ปลายทางระยะไกล:

ls | awk '{print "mv " $1 " ../copied_data/"}' > mv_copied_data
scp mv_copied_data user@source.server.com:/path/to/source/folder

บนแหล่งที่มา:

cd /path/to/source/folder
chmod 777 mv_copied_data
./mv_copied_data

บนปลายทาง:

scp -r user@source.server.com:/path/to/source/folder /path/to/destination/foldeer

โปรดอย่าทำเช่นนี้ 1. อย่าแยก LS 2. คำตอบนั้นอันตรายหากชื่อไฟล์ใดมี- >ช่องว่างขึ้นบรรทัดใหม่หรืออักขระพิเศษอื่น ๆ 3. รหัสยากสำหรับห่วงในสคริปต์หลาม การสร้างโปรแกรมที่รันไทม์นั้นยากและยุ่งยาก (แม้ว่าจะทำโดยโปรแกรมเมอร์มืออาชีพ) ด้วยเหตุผลหลายประการ การสร้างเชลล์สคริปต์นั้นยิ่งเลวร้ายไปกว่านั้นคือความคิดอันยิ่งใหญ่
Ignis
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.