scp hoặc sftp sao chép nhiều tập tin bằng một lệnh duy nhất


314

Tôi muốn sao chép các tập tin từ / đến máy chủ từ xa trong các thư mục khác nhau. Ví dụ, tôi muốn chạy 4 lệnh này cùng một lúc.

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

Cách dễ nhất để làm điều đó là gì?


14
Khi tôi tạo một kịch bản, tôi phải đặt mật khẩu cho mỗi lệnh. Tôi có thể tránh nó không?
dùng987654

11
Tránh lặp lại mật khẩu theo cách này: scp remote: "A / 1.txt A / 2.txt B / 1.txt C / 1.txt" cục bộ: ./
JohnMudd 21/07/2015

stackoverflow.com/a/23748561/874188 (được đề cử là bản sao của cái này) có một kỹ thuật bổ sung tốt đẹp.
tripleee

2
Tôi muốn đề nghị bạn xem xét rsync, có thể nó có thể giúp bạn trong trường hợp này và nhiều trường hợp sắp tới. Sau đó, để tránh nhập mật khẩu (hãy để một mình nhiều lần), bạn nên đọc về khóa sshcông khai / riêng tư, ví dụ: digitalocean.com/community/tutorials/how-to-set-up-ssh-keys--2
mnagel

1
Ví dụ dựa trên câu trả lời của @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' ./.
Eduardo Lucio

Câu trả lời:


420

Sao chép nhiều tệp từ xa sang cục bộ:

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

Sao chép nhiều tệp từ cục bộ sang từ xa:

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

Sao chép nhiều tệp từ xa sang từ xa:

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

Nguồn: http://www.hypexr.org/linux_scp_help.php


5
Lệnh đầu tiên đã bỏ qua một kết thúc "." Và '{a, b, c}' bằng \ {a, b, c \}.
duleshi

11
Tôi nghĩ OP đang cố sao chép nhiều tệp trong nhiều thư mục cục bộ sang nhiều thư mục từ xa, những ví dụ này sẽ không thực hiện được công việc, vì tất cả chúng sẽ quét các tệp vào ~hoặc ./chỉ.
aesede

20
Cẩn thận: không có dấu cách sau dấu phẩy trong dấu ngoặc nhọn. Tôi chỉ mất 10 phút để cố gắng tìm ra lý do tại sao lệnh của tôi không hoạt động và đó là vì không gian.
Deepak

13
@duleshi {a, b, c} không chính xác bằng \ {a, b, c \} khi sao chép từ xa sang cục bộ, vì lần đầu tiên yêu cầu mật khẩu cho mỗi tệp trong khi lần thứ hai chỉ cần mật khẩu một lần.
Marcelo Ventura

15
@MarceloVentura, @duleshi: Ngoài ra, tôi muốn thêm rằng việc sử dụng \{a,b,c\}sẽ chuyển các tệp trong một kết nối / đợt duy nhất (vì chúng sẽ được mở rộng trên máy chủ từ xa), trong khi sử dụng {a,b,c}sẽ mở nhiều kết nối và chi phí là khá đáng chú ý khi chuyển nhiều tập tin
omninonsense

140

Từ địa phương đến máy chủ:

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

Từ máy chủ đến địa phương:

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


6
Đây phải là câu trả lời trên cùng, vì máy chủ không yêu cầu mật khẩu cho mỗi tệp :)
motagirl2

Không hoạt động trên máy khách trên Ubuntu 18 (zsh). Không chắc chắn nơi này nên làm việc. `` `(venv) git: (master) ✗ scp root @ 172,29..xxx.yyy:" / usr / local / bin / kubectl /root/.kube/config "/ tmp / root @ 172,29..xxx. mật khẩu của yyyy: lỗi giao thức: tên tệp không khớp với yêu cầu `` `
jseguillon

3
@ motagirl2 Câu trả lời hàng đầu không yêu cầu mật khẩu cho mỗi tệp miễn là bạn thoát khỏi dấu ngoặc nhọn bằng dấu gạch chéo ngược. Câu trả lời này cho tôi một lỗi mà tập tin không thể tìm thấy.
Sao Diêm Vương

1
@jseguillon Thêm -Ttùy chọn để loại bỏ lỗi đó.
Phục hồi Monica

1
cái thứ hai hoạt động trên máy của tôi nhưng chỉ không có tùy chọn -T
Richard DiSalvo

71

Bạn có thể sao chép toàn bộ thư mục bằng cách sử dụng -rchuyển đổi để nếu bạn có thể cô lập các tệp của mình vào thư mục riêng, bạn có thể sao chép mọi thứ cùng một lúc.

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

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

ví dụ như vậy

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

Hoặc nếu chỉ có một vài trong số họ, bạn có thể sử dụng:

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

Điều này có hoạt động không nếu đích đến của tôi là root và tôi đang làm thư mục etc như ví dụ: scp -r / backups / etc root @ linuxbox: / trong đó nguồn của tôi là một thư mục rất thưa thớt với những thứ như "hosts" và nginx / site có sẵn vv?
Tomachi

47

Như Jiri đã đề cập, bạn có thể sử dụng scp -r user@host:/some/remote/path /some/local/path để sao chép các tệp đệ quy. Điều này giả định rằng có một thư mục chứa tất cả các tệp bạn muốn chuyển (và không có gì khác).

Tuy nhiên, SFTP cung cấp một giải pháp thay thế nếu bạn muốn chuyển các tệp từ nhiều thư mục khác nhau và các đích không giống nhau:

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

Điều này sử dụng cú pháp "here doc" để xác định một chuỗi các lệnh đầu vào SFTP. Cách khác, bạn có thể đặt các lệnh SFTP vào tệp văn bản và thực thisftp user@host -b batchFile.txt


3
Đây là câu trả lời duy nhất thực sự trả lời câu hỏi. Cảm ơn. Tôi đã Googling và phân tích scphướng dẫn sử dụng quá lâu để cố gắng tìm tính năng này và tôi đoán scp không có nó.
sudo

1
Đây dường như là câu trả lời tốt nhất, linh hoạt nhất. Lưu ý: Tôi đã tăng gấp ba lần cho đến khi tôi nhận ra rằng tôi cần sử dụng một đường dẫn đầy đủ như /home/vagrant/Code/thay vì ~/Code/.
Ryan

Đây là câu trả lời tốt nhất, chỉ cần đừng quên thêm - rcho các thư mục
Chris_Rands

25

Câu trả lời với {file1,file2,file3} chỉ hoạt động với bash (trên điều khiển từ xa hoặc cục bộ)

Cách thực sự là:

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

1
Tuyệt diệu! Đôi khi tôi sử dụng vỏ không bash và điều này giúp vô cùng. Không chỉ là cách thực sự, mà là cách đúng.
Paul B.

1
Globbing với {…, …, …}các tác phẩm trong nhiều vỏ, không chỉ trong Bash. Tuy nhiên điều này hoạt động trong bất kỳ vỏ như vậy rõ ràng là tốt hơn.
Piotr Dobrogost

Cần trích dẫn nhiều hơn. Những đường dẫn có thể chứa không gian.
Amit N Nikol

1
Chúng ta đi đây! Tôi đã nâng cao điều đó nhiều lần, nhưng tôi chỉ có thể làm điều đó một lần! Cảm ơn bạn Vouze!
André Pacheco

17

Sau khi chơi với scp một lúc tôi đã tìm ra giải pháp mạnh mẽ nhất:

(Cẩn thận với dấu ngoặc kép đơn và kép)

Địa phương đến từ xa:

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

Từ xa đến địa phương:

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

Lưu ý rằng bất cứ điều gì sau "HOST:" sẽ được gửi đến điều khiển từ xa và được phân tích cú pháp ở đó. Vì vậy, chúng ta phải đảm bảo rằng chúng không được xử lý bởi shell cục bộ. Đó là lý do tại sao dấu ngoặc kép đơn xuất hiện. Dấu ngoặc kép được sử dụng để xử lý khoảng trắng trong tên tệp.

Nếu tất cả các tệp trong cùng một thư mục, chúng ta có thể sử dụng * để khớp tất cả chúng, chẳng hạn như

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

So với việc sử dụng cú pháp "{}" chỉ được hỗ trợ bởi một số shell, thì cú pháp này là phổ biến


Cảm ơn đã giúp với không gian trong tên tập tin. Tôi đã sử dụng phương pháp {} vì vậy tôi cũng phải thoát chúng bằng \ sau khi trích dẫn.
Noumenon

3
Trong trường hợp bạn muốn sử dụng ký tự dấu ngã (~) cho thư mục chính của bạn trong các đường dẫn. Lưu ý cách ~ và / phải nằm ngoài dấu ngoặc kép. `` `scp -r robwaa@192.168.1.101: '~ /" bin / set-vpn-kill-switch "~ /" bin / flush-iptables "' ~ /" "` `
Rob Waa

Các {}cú pháp làm cho nó dễ dàng hơn để sao chép nhiều tập tin từ thư mục đó, là có cách nào để làm điều này với scp -rđể "FILE1" "FILE2"có thể đường dẫn tương đối và đường dẫn không tuyệt đối để các tập tin?
dtasev

15

Cách đơn giản nhất là

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

Vì vậy, danh sách {..} có thể bao gồm các thư mục (A, B và C ở đây là các thư mục; "1.txt" và "2.txt" là tên tệp trong các thư mục đó).

Mặc dù nó sẽ sao chép tất cả bốn tệp này vào một thư mục cục bộ - không chắc đó có phải là thứ bạn muốn không.

Trong trường hợp trên, bạn sẽ kết thúc các tệp từ xa A / 1.txt, A / 2.txt, B / 3.txt và C / 4.txt được sao chép sang một thư mục cục bộ duy nhất, với tên tệp ./1.txt, ./2.txt, ./3.txt và ./4.txt


Điều này sẽ không ghi đè nội dung của A / 1.txt với nội dung của B / 1.txt trên máy cục bộ?
Yves Dorfsman

điểm tốt .. ví dụ điều chỉnh (vì vậy bây giờ nó sẽ không ghi đè) và thêm mô tả. Cảm ơn.
Tagar

Mở rộng cú đúp như thế này là một tính năng của Bash và không khả chuyển sang ví dụ POSIX sh.
tripleee

1
@tripleee, cảm ơn. nó có thể không phải là posix, nhưng nó không chỉ hoạt động trong bash. Tôi sử dụng ksh tất cả thời gian và nó cũng hoạt động ở đó.
Tagar

1
Bạn cũng có thể trộn các thư mục và tệp bằng cách thực hiện:local$ scp -r remote:{A/1.txt,A/2.txt,B/3.txt,C/4.txt,D,F} ./
donhector

13

Vấn đề : Sao chép nhiều thư mục từ máy chủ từ xa sang máy cục bộ bằng một lệnh SCP duy nhất và giữ lại từng thư mục như trong máy chủ từ xa.

Giải pháp : SCP có thể làm điều này một cách dễ dàng. Điều này giải quyết vấn đề khó chịu khi nhập mật khẩu nhiều lần khi sử dụng SCP với nhiều thư mục. Do đó, điều này cũng tiết kiệm rất nhiều thời gian!

ví dụ

# 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: Được thúc đẩy bởi câu trả lời tuyệt vời này: scp hoặc sftp sao chép nhiều tệp bằng một lệnh duy nhất


Dựa trên các nhận xét, điều này cũng hoạt động tốt trong Git Bash trên Windows


3
PS không thêm khoảng trắng giữa các mục. tức là \ {t1, t2, t3 \} ------> Tôi đã lãng phí mười phút ở đây ... lol
kenber siêu

1
Đây là câu trả lời tốt nhất bởi vì khi bạn thoát khỏi niềng răng, nó sẽ được hiểu là một lệnh duy nhất và nó sẽ không hỏi mật khẩu cho mỗi lần chuyển
Amaynut

@Amaynut đúng, chính xác! Điều đó chắc chắn tiết kiệm rất nhiều thời gian và công sức :)
kmario23

12

Sao chép nhiều thư mục:

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

Câu hỏi là làm thế nào để sao chép từ thư mục từ xa sang địa phương, không phải cách khác.
Tagar

5

Bạn có thể làm theo cách này:

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

Điều này sẽ tải tất cả tên tệp được liệt kê vào bất kỳ thư mục địa phương nào bạn đang truy cập.

Đảm bảo không đặt khoảng trắng giữa mỗi tên tệp chỉ sử dụng dấu phẩy ,.


1
Điều này là tốt khi phần mở rộng là như nhau. Nó có thể được viết như /path/to/files/\\{file1.ext,file2.ext,file3.ext\\}thể các tập tin có phần mở rộng khác nhau. Lưu ý với mọi người PowerShell (bây giờ MS đã tham gia nhóm), bạn cần sử dụng `để trốn thoát:/path/to/files/`{file1.ext,file2.ext,file3.ext`}
dtasev

3

LƯU Ý: Tôi xin lỗi trước vì chỉ trả lời một phần câu hỏi trên. Tuy nhiên, tôi thấy các lệnh này hữu ích cho nhu cầu unix hiện tại của tôi.

Tải các tệp cụ thể từ máy cục bộ lên máy từ xa:

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

Tải toàn bộ thư mục từ máy cục bộ lên máy từ xa:

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

Tải xuống toàn bộ thư mục từ máy từ xa đến máy cục bộ:

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


3

Trong trường hợp của tôi, tôi bị hạn chế chỉ sử dụng lệnh sftp.
Vì vậy, tôi đã phải sử dụng một batchfile với sftp. Tôi đã tạo ra một kịch bản như sau. Điều này giả định rằng bạn đang làm việc trong thư mục / tmp và bạn muốn đặt các tệp trong Destdir_on_remote_system trên hệ thống từ xa. Điều này cũng chỉ hoạt động với một đăng nhập không tương tác. Bạn cần thiết lập khóa công khai / riêng tư để có thể đăng nhập mà không cần nhập mật khẩu. Thay đổi khi cần thiết.

#!/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

Lệnh của bạn hoạt động hoàn hảo, nhưng tôi cũng muốn thay đổi tên tệp trong khi gửi cục bộ đến điều khiển từ xa. Tôi đã viết một lệnh: - sshpass -p mật khẩu scp /path/to/file.txt root @ hostname: /path/newfile.txt

Nhưng nó báo lỗi rằng /path/newfile.txt: Không tìm thấy tệp hoặc thư mục nào như vậy giúp tôi trong tình huống này


Hãy chắc chắn rằng thư mục từ xa hostname:/path/thực sự tồn tại và có thể truy cập.
Amit N Nikol

1

scp sử dụng ssh để truyền dữ liệu với cùng một xác thực và cung cấp bảo mật tương tự như ssh.

Một cách thực hành tốt nhất ở đây là triển khai "SSH KEYS AND AUTUBENTATION AUTHENTICATION". Với điều này, bạn có thể viết các tập lệnh của mình mà không phải lo lắng về xác thực. Đơn giản như vậy.

Xem SSH-KEYGEN LÀ GÌ


1

Trong trường hợp cụ thể trong đó tất cả các tệp có cùng phần mở rộng nhưng có hậu tố khác nhau (giả sử số tệp nhật ký), bạn sử dụng như sau:

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

Điều này sẽ sao chép tất cả các tệp có tên some_log_file từ thư mục đã cho trong điều khiển từ xa, tức là- some_log_file.1, some_log_file.2, some_log_file.3 ....


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

cảm ơn, nhưng nó chỉ là một ví dụ và tên tập tin hoặc thư mục thực tế phức tạp hơn. Nhưng tôi có một danh sách của họ.
dùng987654

Bạn có thể mô tả những người bằng một biểu thức thông thường?
unxnut

Có thể bảo tồn cấu trúc thư mục tương tự trong thư mục đích bằng cách sử dụng biểu thức chính quy không?
dùng987654

1
Có, bạn sẽ có thể làm điều đó với -rtùy chọn scp. Và bạn có thể bảo tồn các thuộc tính khác (như dấu thời gian) với -ptùy chọn.
unxnut
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.