SCP หรือ SFTP คัดลอกหลายไฟล์ด้วยคำสั่งเดียว


314

ฉันต้องการคัดลอกไฟล์จาก / ไปยังเซิร์ฟเวอร์ระยะไกลในไดเรกทอรีที่แตกต่างกัน ตัวอย่างเช่นฉันต้องการเรียกใช้คำสั่ง 4 เหล่านี้ในครั้งเดียว

scp remote:A/1.txt local:A/1.txt
scp remote:A/2.txt local:A/2.txt
scp remote:B/1.txt local:B/1.txt
scp remote:C/1.txt local:C/1.txt

วิธีที่ง่ายที่สุดในการทำเช่นนั้นคืออะไร?


14
เมื่อฉันสร้างสคริปต์ฉันต้องใส่รหัสผ่านสำหรับแต่ละคำสั่ง ฉันจะหลีกเลี่ยงได้ไหม
user987654

11
หลีกเลี่ยงการทำรหัสผ่านซ้ำด้วยวิธีนี้: scp remote: "A / 1.txt A / 2.txt B / 1.txt C / 1.txt" ในพื้นที่: ./
JohnMudd

stackoverflow.com/a/23748561/874188 (เสนอชื่อซ้ำกับอันนี้) มีเทคนิคเพิ่มเติมที่ดี
tripleee

2
ฉันขอแนะนำให้คุณดูrsyncบางทีมันอาจช่วยคุณได้ในกรณีนี้และอีกหลายกรณี จากนั้นเพื่อหลีกเลี่ยงการป้อนรหัสผ่าน (ให้อยู่คนเดียวหลาย ๆ ครั้ง) คุณควรอ่านเกี่ยวกับsshกุญแจสาธารณะ / กุญแจส่วนตัวเช่นdigitalocean.com/community/tutorials/how-to-set-up-ssh-keys--2
mnagel

1
ตัวอย่างขึ้นอยู่กับคำตอบ @JohnMudd scp root@192.168.56.120:'/etc/openvpn/ca.crt /etc/openvpn/client/client0.crt /etc/openvpn/client/client0.key /etc/openvpn/client/ta.key' ./'s:
Eduardo Lucio

คำตอบ:


420

คัดลอกหลายไฟล์จากระยะไกลสู่ท้องถิ่น:

$ scp your_username@remote.edu:/some/remote/directory/\{a,b,c\} ./

คัดลอกหลายไฟล์จากโลคัลเป็นรีโมต:

$ scp foo.txt bar.txt your_username@remotehost.edu:~
$ scp {foo,bar}.txt your_username@remotehost.edu:~
$ scp *.txt your_username@remotehost.edu:~

คัดลอกหลายไฟล์จากระยะไกลไปยังระยะไกล:

$ scp your_username@remote1.edu:/some/remote/directory/foobar.txt \
your_username@remote2.edu:/some/remote/directory/

ที่มา: http://www.hypexr.org/linux_scp_help.php


5
คำสั่งแรกละเว้นการสิ้นสุด "." และ '{a, b, c}' เท่ากับ \ {a, b, c \}
duleshi

11
ฉันคิดว่า OP กำลังพยายามคัดลอกไฟล์หลายไฟล์ในหลาย ๆ โฟลเดอร์ในเครื่องไปยังหลาย ๆ โฟลเดอร์จากระยะไกลตัวอย่างเหล่านี้จะไม่ทำงานเนื่องจากจะทำการคัดลอกไฟล์ไปยัง~หรือ./เพียงอย่างเดียว
aesede

20
ระวัง: ไม่มีช่องว่างหลังจากเครื่องหมายจุลภาคภายในเครื่องหมายปีกกา ฉันใช้เวลา 10 นาทีเพื่อหาสาเหตุที่คำสั่งของฉันไม่ทำงานและเป็นเพราะช่องว่าง
deepak

13
@duleshi {a, b, c} ไม่เท่ากับ \ {a, b, c \} เมื่อทำการคัดลอกจากระยะไกลไปยังโลคอลสำหรับครั้งแรกต้องใช้รหัสผ่านสำหรับแต่ละไฟล์ในขณะที่ที่สองต้องใช้รหัสผ่านเพียงครั้งเดียว
Marcelo Ventura

15
@MarceloVentura, @duleshi: นอกจากนี้ฉันต้องการเพิ่มว่าการใช้\{a,b,c\}จะถ่ายโอนไฟล์ในการเชื่อมต่อ / แบทช์เดียว (เนื่องจากจะขยายในโฮสต์ระยะไกล) ในขณะที่ใช้{a,b,c}จะเปิดการเชื่อมต่อหลายรายการและค่าใช้จ่ายคือ ค่อนข้างเห็นได้ชัดเมื่อถ่ายโอนไฟล์จำนวนมาก
omninonsense

140

จากท้องถิ่นสู่เซิร์ฟเวอร์:

scp file1.txt file2.sh username@ip.of.server.copyto:~/pathtoupload

จากเซิร์ฟเวอร์เป็นท้องถิ่น:

scp -T username@ip.of.server.copyfrom:"file1.txt file2.txt" "~/yourpathtocopy"


6
นี่ควรเป็นคำตอบที่อยู่ด้านบนเนื่องจากเซิร์ฟเวอร์ไม่ขอรหัสผ่านสำหรับแต่ละไฟล์ :)
469243

ไม่ทำงานกับไคลเอนต์บน Ubuntu 18 (zsh) ไม่แน่ใจว่าควรใช้ที่ใด `` `(venv) ➜ git: (มาสเตอร์) ✗ scp root @ 172.29..xxx.yyy:" / usr / local / bin / kubectl /root/.kube/config "/ tmp / root @ 172.29..xxx รหัสผ่านของ yyy: ข้อผิดพลาดของโปรโตคอล: ชื่อไฟล์ไม่ตรงกับคำขอ `` `
jseguillon

3
@ motagirl2 คำตอบยอดนิยมไม่ถามรหัสผ่านสำหรับแต่ละไฟล์ตราบใดที่คุณหนีวงเล็บเหลี่ยมด้วยแบ็กสแลช คำตอบนี้ทำให้ฉันมีข้อผิดพลาดที่ไม่พบไฟล์
พลูโต

1
@jseguillon เพิ่ม-Tตัวเลือกเพื่อระงับข้อผิดพลาดนั้น
Reinstate Monica

1
คนที่สองงานบนเครื่องของฉัน แต่ไม่มีตัวเลือก -T
ริชาร์ด DiSalvo

71

คุณสามารถคัดลอกทั้งไดเรกทอรีโดยใช้-rสวิตช์ดังนั้นหากคุณสามารถแยกไฟล์ของคุณลงในไดเรกทอรีของตัวเองคุณสามารถคัดลอกทุกสิ่งได้ในครั้งเดียว

scp -r ./dir-with-files user@remote-server:upload-path

scp -r user@remote-server:path-to-dir-with-files download-path

ตัวอย่างเช่น

scp -r root@192.168.1.100:/var/log ~/backup-logs

หรือหากมีเพียงไม่กี่ข้อคุณสามารถใช้:

scp 1.txt 2.txt 3.log user@remote-server:upload-path

ใช้งานได้ไหมหากปลายทางของฉันเป็นรูทและฉันกำลังทำไดเร็กทอรี etc อย่างเช่น: scp -r / backups / etc root @ linuxbox: / โดยที่แหล่งที่มาของฉันเป็นไดเรคทอรี่ที่กระจัดกระจายมาก - พร้อมใช้งาน ฯลฯ
Tomachi

47

ดังที่จิริกล่าวไว้คุณสามารถใช้scp -r user@host:/some/remote/path /some/local/pathเพื่อคัดลอกไฟล์ซ้ำ สมมติว่ามีไดเรกทอรีเดียวที่มีไฟล์ทั้งหมดที่คุณต้องการถ่ายโอน (และไม่มีอะไรอื่น)

อย่างไรก็ตาม SFTP เป็นทางเลือกหากคุณต้องการถ่ายโอนไฟล์จากหลาย ๆ ไดเรกทอรีและปลายทางนั้นไม่เหมือนกัน:

sftp user@host << EOF
  get /some/remote/path1/file1 /some/local/path1/file1
  get /some/remote/path2/file2 /some/local/path2/file2
  get /some/remote/path3/file3 /some/local/path3/file3
EOF

สิ่งนี้ใช้ไวยากรณ์"here doc"เพื่อกำหนดลำดับของคำสั่งอินพุต SFTP คุณสามารถใส่คำสั่ง SFTP ลงในไฟล์ข้อความและดำเนินการแทนได้sftp user@host -b batchFile.txt


3
นี่เป็นคำตอบเดียวที่ตอบคำถามได้จริง ขอบคุณ ฉันได้ Googling และวิเคราะห์scpคู่มือมานานแล้วที่พยายามค้นหาคุณลักษณะนี้และฉันคิดว่า scp ไม่มีอยู่
sudo

1
นี่เป็นคำตอบที่ดีที่สุดและยืดหยุ่นที่สุด หมายเหตุ: ผมได้ดีดกลับขึ้นจนฉันตระหนักว่าฉันจำเป็นต้องใช้เส้นทางแบบเต็มเช่นแทน/home/vagrant/Code/ ~/Code/
Ryan

นี่เป็นคำตอบที่ดีที่สุดอย่าลืมเพิ่ม- rไดเรกทอรี
Chris_Rands

25

คำตอบด้วย {file1,file2,file3}ใช้ได้กับการทุบตีเท่านั้น (ในระยะไกลหรือในพื้นที่)

วิธีที่แท้จริงคือ:

scp user@remote:'/path1/file1 /path2/file2 /path3/file3' /localPath

1
Fantastic! บางครั้งฉันก็ใช้เปลือกที่ไม่ทุบตีและสิ่งนี้จะช่วยได้อย่างมากมาย ไม่ใช่แค่ของจริง แต่เป็นวิธีที่ถูกต้อง
Paul B.

1
กลมกลืนกับ{…, …, …}งานในหลาย ๆ เชลล์ไม่เพียง แต่ใน Bash อย่างไรก็ตามวิธีนี้ใช้ได้กับทุกเชลล์ดังนั้นจึงดีกว่าอย่างชัดเจน
Piotr Dobrogost

ต้องการข้อความเพิ่มเติม เส้นทางเหล่านั้นสามารถมีช่องว่าง
Amit Naidu

1
เราจะไปที่นั่น! ฉันลงคะแนนหลายครั้ง แต่ฉันทำได้เพียงครั้งเดียว! ขอบคุณ Vouze!
André Pacheco

17

หลังจากเล่นกับ SCP มาพักหนึ่งแล้วฉันก็ได้พบกับทางออกที่แข็งแกร่งที่สุดแล้ว:

(ระวังเครื่องหมายคำพูดเดี่ยวและคู่)

ท้องถิ่นถึงระยะไกล:

scp -r "FILE1" "FILE2" HOST:'"DIR"'

รีโมตเป็นโลคัล:

scp -r HOST:'"FILE1" "FILE2"' "DIR"

โปรดสังเกตว่าอะไรก็ตามหลังจาก "HOST:" จะถูกส่งไปยังรีโมตและวิเคราะห์ที่นั่น ดังนั้นเราต้องตรวจสอบให้แน่ใจว่าไม่ได้ประมวลผลโดยเชลล์โลคัล นี่คือเหตุผลที่เครื่องหมายอัญประกาศเดี่ยวมาเครื่องหมายอัญประกาศคู่ถูกใช้เพื่อจัดการช่องว่างในชื่อไฟล์

หากไฟล์ทั้งหมดอยู่ในไดเรกทอรีเดียวกันเราสามารถใช้ * เพื่อจับคู่พวกเขาทั้งหมดเช่น

scp -r "DIR_IN"/*.txt HOST:'"DIR"'
scp -r HOST:'"DIR_IN"/*.txt' "DIR"

เปรียบเทียบกับการใช้ไวยากรณ์ "{}" ซึ่งเชลล์บางตัวรองรับเท่านั้นเชลล์นี้เป็นสากล


ขอบคุณที่ช่วยเว้นวรรคในชื่อไฟล์ ฉันใช้วิธี {} ดังนั้นฉันจึงต้องหนีพวกมันด้วย \ หลังจากการอ้างอิง
Noumenon

3
ในกรณีที่คุณต้องการใช้อักขระ tilde (~) สำหรับโฮมไดเร็กตอรี่ของคุณในพา ธ สังเกตว่าเครื่องหมาย ~ และ / ต้องอยู่นอกเครื่องหมายคำพูดอย่างไร `` `scp -r robwaa@192.168.1.101: '~ /" bin / set-vpn-kill-switch "~ /" bin / flush-iptables "' ~ /" "` ``
Rob Waa

{}ไวยากรณ์ทำให้ง่ายต่อการคัดลอกไฟล์จากหลายไดเรกทอรีเดียวกันจะมีวิธีการทำเช่นนี้กับใด ๆscp -rเพื่อให้"FILE1" "FILE2"สามารถเป็นทางญาติและเส้นทางที่ไม่สมบูรณ์ไปยังไฟล์?
dtasev

15

วิธีที่ง่ายที่สุดคือ

local$ scp remote:{A/1,A/2,B/3,C/4}.txt ./

ดังนั้นรายการ {.. } สามารถรวมไดเรกทอรี (A, B และ C นี่คือไดเรกทอรี; "1.txt" และ "2.txt" เป็นชื่อไฟล์ในไดเรกทอรีเหล่านั้น)

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

ในกรณีข้างต้นคุณจะสิ้นสุดไฟล์ระยะไกล A / 1.txt, A / 2.txt, B / 3.txt และ C / 4.txt คัดลอกไปยังไดเรกทอรีท้องถิ่นเดียวที่มีชื่อไฟล์. 1/4.txt, ./2.txt, ./3.txt และ ./4.txt


สิ่งนี้จะไม่เขียนทับเนื้อหาของ A / 1.txt กับเนื้อหาของ B / 1.txt บนเครื่องท้องถิ่นหรือไม่
Yves Dorfsman

จุดดี .. ตัวอย่างที่ปรับแล้ว (ดังนั้นตอนนี้มันจะไม่เขียนทับ) และเพิ่มคำอธิบาย ขอบคุณ
Tagar

ขยายรั้งเช่นนี้เป็นคุณลักษณะทุบตีและไม่พกพาไปเช่น shPOSIX
tripleee

1
@tripleee ขอบคุณ มันอาจจะไม่ได้เป็น posix แต่ทำงานได้ไม่เพียง แต่ในการทุบตี ฉันใช้ ksh ตลอดเวลาและใช้งานได้เช่นกัน
Tagar

1
นอกจากนี้คุณยังสามารถผสม dirs และไฟล์โดยทำ:local$ scp -r remote:{A/1.txt,A/2.txt,B/3.txt,C/4.txt,D,F} ./
donhector

13

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

ทางออก : SCP สามารถทำสิ่งนี้ได้อย่างง่ายดาย วิธีนี้จะช่วยแก้ปัญหาที่น่ารำคาญของการป้อนรหัสผ่านหลายครั้งเมื่อใช้ SCP กับหลาย ๆ โฟลเดอร์ ดังนั้นสิ่งนี้ช่วยประหยัดเวลาได้มาก!

เช่น

# copies folders t1, t2, t3 from `test` to your local working directory
# note that there shouldn't be any space in between the folder names;
# we also escape the braces.
# please note the dot at the end of the SCP command

~$ cd ~/working/directory
~$ scp -r username@contact.server.de:/work/datasets/images/test/\{t1,t2,t3\}  .

PS: แรงบันดาลใจจากคำตอบที่ดีนี้: scp หรือ sftp คัดลอกหลายไฟล์ด้วยคำสั่งเดียว


จากความคิดเห็นสิ่งนี้ใช้งานได้ดีในGit Bash บน Windows


3
PS ไม่เพิ่มช่องว่างระหว่างรายการ เช่น \ {t1, t2, t3 \} ------> ฉันเสียเวลาสิบนาทีที่นี่ ... lol
kenberkeley

1
นี่เป็นคำตอบที่ดีที่สุดเพราะเมื่อคุณหลบเลี่ยงเครื่องมือจัดฟันมันจะถูกตีความว่าเป็นคำสั่งเดียวและจะไม่ถามรหัสผ่านสำหรับการถ่ายโอนแต่ละครั้ง
Amaynut

@ Amaynut ใช่แน่นอน! แน่นอนช่วยประหยัดเวลาและความพยายามอย่างมาก :)
kmario23

12

คัดลอกหลายไดเรกทอรี:

scp -r dir1 dir2 dir3 admin@127.0.0.1:~/

คำถามคือวิธีการคัดลอกจากไดเรกทอรีระยะไกลไปยังท้องถิ่นไม่ใช่วิธีอื่น ๆ
Tagar

5

คุณสามารถทำสิ่งนี้ได้:

scp hostname@serverNameOrServerIp:/path/to/files/\\{file1,file2,file3\\}.fileExtension ./

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

ตรวจสอบให้แน่ใจว่าไม่ได้เว้นวรรคระหว่างแต่ละชื่อไฟล์ให้ใช้คอมม่า,เท่านั้น


1
นี่เป็นสิ่งที่ดีเมื่อส่วนขยายเหมือนกัน มันสามารถเขียนได้ราวกับ/path/to/files/\\{file1.ext,file2.ext,file3.ext\\}ว่าไฟล์นั้นมีนามสกุลต่างกัน หมายเหตุถึงคน PowerShell (ตอนนี้ MS ได้เข้าร่วมปาร์ตี้) คุณต้องใช้`เพื่อหลบหนีแทน:/path/to/files/`{file1.ext,file2.ext,file3.ext`}
dtasev

3

หมายเหตุ: ฉันต้องขออภัยล่วงหน้าสำหรับการตอบเพียงบางส่วนของคำถามข้างต้น อย่างไรก็ตามฉันพบว่าคำสั่งเหล่านี้มีประโยชน์สำหรับความต้องการยูนิกซ์ปัจจุบันของฉัน

การอัพโหลดไฟล์เฉพาะจากเครื่องท้องถิ่นไปยังเครื่องระยะไกล:

~/Desktop/dump_files$ scp file1.txt file2.txt lab1.cpp etc.ext your-user-id@remotemachine.edu:Folder1/DestinationFolderForFiles/

อัพโหลดไดเรกทอรีทั้งหมดจากเครื่องท้องถิ่นไปยังเครื่องระยะไกล:

~$ scp -r Desktop/dump_files your-user-id@remotemachine.edu:Folder1/DestinationFolderForFiles/

การดาวน์โหลดไดเรกทอรีทั้งหมดจากเครื่องระยะไกลไปยังเครื่องท้องถิ่น:

~/Desktop$ scp -r your-user-id@remote.host.edu:Public/web/ Desktop/


3

ในกรณีของฉันฉันถูก จำกัด ให้ใช้เฉพาะคำสั่ง sftp
ดังนั้นฉันต้องใช้ batchfile กับ sftp ฉันสร้างสคริปต์ดังต่อไปนี้ สิ่งนี้ถือว่าคุณทำงานในไดเร็กทอรี / tmp และคุณต้องการวางไฟล์ใน destdir_on_remote_system บนระบบรีโมต นอกจากนี้ยังใช้งานได้เฉพาะกับการเข้าสู่ระบบแบบไม่โต้ตอบ คุณต้องตั้งค่าคีย์สาธารณะ / ส่วนตัวเพื่อให้คุณสามารถเข้าสู่ระบบโดยไม่ต้องป้อนรหัสผ่าน เปลี่ยนได้ตามต้องการ

#!/bin/bash

cd /tmp
# start script with list of files to transfer
ls -1 fileset1* > batchfile1
ls -1 fileset2* >> batchfile1

sed -i -e 's/^/put /' batchfile1
echo "cd destdir_on_remote_system" > batchfile
cat batchfile1 >> batchfile
rm batchfile1

sftp -b batchfile user@host

2

คำสั่งของคุณใช้งานได้ดี แต่ฉันต้องการเปลี่ยนชื่อไฟล์ในขณะที่ส่งโลคัลเป็นรีโมต ฉันเขียนคำสั่ง: - sshpass -p รหัสผ่าน scp /path/to/file.txt root @ hostname: /path/newfile.txt

แต่มันให้ข้อผิดพลาดที่ /path/newfile.txt: ไม่พบไฟล์หรือไดเรกทอรีเช่นนี้โปรดช่วยฉันในสถานการณ์นี้


ตรวจสอบให้แน่ใจว่าไดเรกทอรีระยะไกลhostname:/path/มีอยู่จริงและสามารถเข้าถึงได้
Amit Naidu

1

scp ใช้ ssh สำหรับการถ่ายโอนข้อมูลด้วยการรับรองความถูกต้องเดียวกันและให้ความปลอดภัยเช่นเดียวกับ ssh

แนวทางปฏิบัติที่ดีที่สุดที่นี่คือการใช้ "คีย์ SSH และการรับรองคีย์สาธารณะ" ด้วยวิธีนี้คุณสามารถเขียนสคริปต์ของคุณโดยไม่ต้องกังวลเกี่ยวกับการตรวจสอบ เรียบง่ายเหมือนที่

ดูว่าSSH-KEYGEN คืออะไร


1

ในกรณีเฉพาะที่ไฟล์ทั้งหมดมีนามสกุลเดียวกัน แต่มีคำต่อท้ายที่แตกต่างกัน (พูดจำนวนไฟล์บันทึก) คุณใช้สิ่งต่อไปนี้:

scp user_name@ip.of.remote.machine:/some/log/folder/some_log_file.* ./

สิ่งนี้จะคัดลอกไฟล์ทั้งหมดที่ชื่อว่า some_log_file จากโฟลเดอร์ที่กำหนดภายในรีโมตนั่นคือ some_log_file.1, some_log_file.2, some_log_file.3 ....


-1
scp remote:"[A-C]/[12].txt" local:

ขอบคุณ แต่มันเป็นเพียงตัวอย่างและชื่อไฟล์หรือไดเรกทอรีที่แท้จริงมีความซับซ้อนมากขึ้น แต่ฉันมีรายการของพวกเขา
user987654

คุณสามารถอธิบายสิ่งเหล่านั้นด้วยการแสดงออกปกติได้หรือไม่?
unxnut

เป็นไปได้หรือไม่ที่จะคงโครงสร้างไดเรกทอรีเดิมในไดเรกทอรีเป้าหมายโดยใช้นิพจน์ทั่วไป
user987654

1
ใช่คุณควรจะสามารถที่จะทำอย่างนั้นกับตัวเลือกในการ-r scpและคุณสามารถรักษาคุณลักษณะอื่น ๆ (เช่นการประทับเวลา) ด้วย-pตัวเลือก
unxnut
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.