scp或sftp使用单个命令复制多个文件


313

我想将文件复制到不同目录中的远程服务器,或从其中复制文件。例如,我想一次运行这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 2013年

11
避免以这种方式重复输入密码:scp远程:“ A / 1.txt A / 2.txt B / 1.txt C / 1.txt”本地:./
JohnMudd

stackoverflow.com/a/23748561/874188(被提名为与此副本的副本)具有很好的附加技术。
三人房

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' ./
爱德华多·卢西奥

Answers:


418

将多个文件从远程复制到本地:

$ 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 2014年

11
我认为OP试图将多个本地文件夹中的多个文件复制到多个远程文件夹中,这些示例将无法完成工作,因为它们都将文件压缩到~./仅复制到文件。
aesede 2015年

20
当心:大括号内的逗号后没有空格。我只花了10分钟的时间来弄清楚为什么我的命令不起作用,原因是因为空格。
deepak

13
从远程复制到本地时,@ duleshi {a,b,c}与\ {a,b,c \}不完全相同,因为第一个文件要求输入每个文件的密码,而第二个文件仅需输入一次密码。
Marcelo Ventura

15
@ MarceloVentura,@ duleshi:另外,我想补充一点,using \{a,b,c\}将在单个连接/批处理中传输文件(因为它们将在远程主机上扩展),而using {a,b,c}将打开多个连接,并且开销是传输许多文件时非常明显
omn​​inonsense 2016年

139

从本地到服务器:

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

从服务器到本地:

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


6
这应该是最重要的答案,因为服务器不需要输入每个文件的密码:)
motagirl2

在Ubuntu 18(zsh)的客户端上不起作用。不知道这应该在哪里工作。```(venv)➜git:(master)✗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选项以抑制该错误。
恢复莫妮卡

1
第二个可以在我的机器上工作,但仅不带-T选项
Richard DiSalvo

71

您可以使用-rswitch 复制整个目录,因此,如果您可以将文件隔离到自己的目录中,则可以一次复制所有内容。

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:/,这是否有效?我的源代码是一个非常稀疏的目录,其中包含“ hosts”和nginx / sites -可用等?
Tomachi

47

如Jiri所述,您可以用来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
这是实际回答问题的唯一答案。谢谢。我一直在scp搜寻Google 手册并对其进行分析,试图找到该功能的时间太长了,我想scp没有它。
sudo

1
这似乎是最好,最灵活的答案。注意:我被绊倒了,直到意识到自己需要使用/home/vagrant/Code/代替的完整路径~/Code/
瑞安

这是最好的答案,只是不要忘记- r为目录添加
Chris_Rands

25

答案{file1,file2,file3}仅适用于bash(在远程或本地)

真正的方法是:

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

1
太棒了!有时我会使用非bash外壳,这将带来不可估量的帮助。不仅是真实的方法,而且是正确的方法。
Paul B.

1
{…, …, …}在许多shell中,不仅在Bash中,窃听都是有效的。但是,这适用于任何外壳,因此显然更好。
Piotr Dobrogost

需要更多报价。这些路径可以包含空格。
阿米特·奈杜

1
好了!我会投票很多次,但是我只能做一次!谢谢Vouze!
安德烈·帕切科

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"

与仅某些shell支持的“ {}”语法相比,该语法是通用的


感谢您为文件名中的空格提供帮助。我使用的是{}方法,因此引用后也必须用\对其进行转义。
Noumenon

3
如果要在路径中的主目录中使用波浪号(〜)。请注意〜和/必须位于引号之外。```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.txt, ./2.txt、./3.txt和./4.txt


这会不会在本地计算机上用B / 1.txt的内容覆盖A / 1.txt的内容?
伊夫·多夫斯曼

好点..调整示例(因此现在不会覆盖)并添加了描述。谢谢。
塔加

像这样的Brace扩展是Bash功能,不能移植到POSIX等sh
三人房

1
@tripleee,谢谢。它可能不是posix,但它不仅适用于bash。我一直在使用ksh,它也在那里工作。
塔加

1
您还可以执行以下操作来混合目录和文件: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使用单个命令复制多个文件


根据评论,这在Windows上的Git Bash中也可以正常工作


3
PS不会在项目之间添加空格。即\ {t1,t2,t3 \} ------>我在这里浪费了十分钟...大声笑
kenberkeley 18/12/20

1
这是最佳答案,因为当您转义括号时,它将被解释为单个命令,并且不会要求每次传输输入密码
Amaynut

@Amaynut是的,完全是!那当然可以节省很多时间和精力:)
kmario23 '19

12

复制多个目录:

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

问题是如何从远程目录复制到本地目录,而不是其他方式。
塔加尔

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

注意:我只为回答上述问题的一部分而致歉。但是,我发现这些命令对于我当前的unix需求很有用。

将特定文件从本地计算机上传到远程计算机:

~/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命令。
因此,我不得不将批处理文件与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 password scp /path/to/file.txt root @ hostname:/path/newfile.txt

但是它给出了/path/newfile.txt的错误:在这种情况下找不到这样的文件或目录,请帮我


确保远程目录hostname:/path/实际上存在并且可以访问。
阿米特·奈杜

1

scp使用ssh进行具有相同身份验证的数据传输,并提供与ssh相同的安全性。

此处的最佳实践是实施“ SSH密钥和公共密钥认证”。这样,您就可以编写脚本而不必担心身份验证。就那么简单。

请参阅什么是SSH密钥生成器


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 2013年

您可以用正则表达式描述它们吗?
unxnut

是否可以通过使用正则表达式在目标目录中保留相同的目录结构?
user987654 2013年

1
是的,您应该可以使用来执行此-r操作scp。您可以使用options保留其他属性(例如时间戳)-p
unxnut
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.