使用指定端口号的SCP

1103

我正在尝试从远程服务器将文件通过scp传输到本地机器。只有端口80可用。

我尝试过:

scp -p 80 username@www.myserver.com:/root/file.txt .

我执行scp命令时遇到了错误:cp: 80: No such file or directory

如何在scp命令中指定端口号?


72
端口应该使用大写字母 -P 80。 - Eliethesaiyan
14个回答

1900

与ssh不同,scp使用大写的P开关来设置端口,而不是小写的p:

scp -P 80 ... # Use port 80 to bypass the firewall, instead of the scp default

使用小写字母p开关与scp一起使用以保留时间和模式。

这是来自scp手册页的摘录,其中包含有关这两个开关的所有详细信息,以及解释为什么选择大写P用于scp:

-P port 指定在远程主机上连接的端口。请注意,此选项使用大写“P”,因为-p已经保留用于在rcp(1)中保留文件的时间和模式。

-p 保留原始文件的修改时间、访问时间和模式。

奖励提示:如何确定正在使用哪个/某个SSH守护程序接受SSH连接的端口?

可以通过使用netstat实用程序来回答这个问题,如下所示:

sudo netstat -tnlp | grep sshd

或者使用更易读的基于单词的netstat选项名称:

sudo netstat --tcp --numeric-ports --listening --program | grep sshd

假设您的ssh守护程序配置为默认值监听端口,您将看到以下输出(稍微修整列之间的空格,以便在不必滚动的情况下查看整个表):

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address  Foreign Address  State       ID/Program name
tcp      0      0   0.0.0.0:22     0.0.0.0:*        LISTEN      888/sshd: /usr/sbin 
tcp6     0      0   :::22          :::*             LISTEN      888/sshd: /usr/sbin 

重要提示

对于上述示例,使用sudo以管理员权限运行netstat,以便能够查看所有程序名称。如果您以普通用户身份运行netstat(即没有sudo和假设您没有通过其他方法获得管理员权限),则仅会显示UID为所有者的套接字所显示的程序名称。属于其他用户的套接字的程序名称将不会显示(即将被隐藏,并显示一个占位符破折号):

Proto Recv-Q Send-Q Local Address   Foreign Address  State       ID/Program name
tcp        0      0 127.0.0.1:46371 0.0.0.0:*        LISTEN      4489/code
...
tcp        0      0 0.0.0.0:111     0.0.0.0:*        LISTEN      -                   
tcp        0      0 127.0.0.53:53   0.0.0.0:*        LISTEN      -                   
tcp        0      0 0.0.0.0:22      0.0.0.0:*        LISTEN      -                   
...

更新和旁注以回应其中一个(被赞数很高的)评论:

关于 Abdull 关于 scp 选项顺序的评论,他建议的是:

scp -r some_directory -P 80 ...

..., 选项和参数交错在一起,因为 -r 开关不接受附加参数,而 some_directory 被视为命令的第一个参数,使得 -P 和所有后续的命令行参数看起来像是命令的附加参数(即,带连字符的前缀参数不再被视为开关)。

getopt(1) 明确定义了参数必须在选项(即,开关)之后,而不是与其混杂:

getopt 的参数可以分为两部分:修改 getopt 解析方式的选项(见 SYNOPSIS 中的选项和 optstring),和被解析的参数(见 SYNOPSIS 中的参数)。第二部分将从第一个非选项参数开始,该参数不是选项参数,或者从第一个 '--' 出现的位置开始。如果在第一部分中没有找到 '-o' 或 '--options' 选项,则第二部分的第一个参数将用作短选项字符串。

由于 -r 命令行选项不需要进一步的参数,所以 some_directory 是“第一个非选项参数且不是选项参数”的参数。因此,正如 getopt(1) 手册清楚地说明的那样,其后的所有命令行参数(即,-P 80 ...)都被假定为非选项(和非选项参数)。

因此,实际上,这是 getopt(1) 如何看待所呈现的示例,其选项结束和参数开始由灰色文本标记:

scp -r some_directory -P 80 ...

这与 scp 的行为无关,而与 POSIX 标准应用程序如何使用 C 函数集 getopt(3) 解析命令行选项有关。

有关命令行排序和处理的更多详细信息,请使用以下命令阅读 getopt(1) 手册页:

man 1 getopt

115
顺便提一句,scp 命令需要正确的选项顺序:scp -r some_directory -P 80 ... 是无效的——但是 scp -P 80 -r some_directory ... 是有效的。 - Abdull
9
通常在Linux中,命令后面跟着选项,然后是指令/数值。 - Gary
2
@Abdull 注意:scp -r -p 50193 /path/to/directory 同样适用。文件路径参数与-r递归选项无关。 - Benjamin
7
@本杰明:除非你想使用端口号50193,否则你应该将“p”大写。 - None
2
@Abdull:在http://askubuntu.com/a/307078/37574上有一个答案解释了“-P”参数的顺序。基本上,端口必须在主机之前。这既可以防止歧义,也可以允许两个“-P”参数,如果两个主机都是远程的。 - mwfearnley
显示剩余4条评论

112

另一个提示:在scp命令后面加上“-P”选项,不管你ssh连接的是第二台机器(也就是目标机器)还是其他机器。例如:

scp -P 2222 /absolute_path/source-folder/some-file user@example.com:/absolute_path/destination-folder

63

你知道比 -P 更酷的是什么吗?没有。

如果你会多次使用这个服务器,请设置/创建一个像这样的条目的~/.ssh/config文件:

Host www.myserver.com
    Port 80
或者
Host myserver myserver80 short any.name.u.want yes_anything well-within-reason
    HostName www.myserver.com
    Port 80
    User username

然后您可以使用:

scp username@www.myserver.com:/root/file.txt .

或者

scp short:/root/file.txt .

您可以在ssh、scp、rsync、git等中的“主机”行上使用任何内容。

有很多配置选项可以在配置文件中使用,请参见:

man ssh_config


5
唯一的解决方案允许在不同端口上监听 ssh 的服务器之间使用 scp -3 命令。类似于 scp -3 -P 123 server1:/file -P 456 server2:/file 的替代方法无法正常工作,因为 scp 假定两个服务器的端口相同。 - user88595
最佳解决方案,源文件来自远程机器。 - Sadat

40

我正在使用非标准端口,并像这样在文件之间复制文件:

scp -P 1234 user@[ip address or host name]:/var/www/mywebsite/dumps/* /var/www/myNewPathOnCurrentLocalMachine

这仅适用于偶尔使用,如果它基于计划重复出现,您应该使用rsync和cron job进行操作。


18

要在scp命令中使用另一个端口,请像这样使用大写字母P

scp -P port-number source-file/directory user@domain:/destination

雅阿里


1
如何提供目标端口而不是发送者的端口? - Ahmed Suror

9

可以使用scp协议路径指定端口:scp://[user@]host[:port][/path]

来自scp手册:

源和目标可以指定为本地路径名、可选路径的远程主机形式[user@]host:path,或形式为scp://[user@]host[:port][/path]的URI。为了避免scp将包含“:”的文件名视为主机说明符,可以使用绝对或相对路径名来明确指定本地文件名。

示例:

scp local/filename scp://user@acme.com:22222/path/to/filename
scp scp://userA@foo.com:22222/path/to/filename scp://userB@bar.com:33333/path/to/filename

请注意,如果您的路径是从根目录开始的,则路径中需要有两个/。例如:
scp local/filename scp://user@acme.com:22222//root/path/to/filename

当源和目的地是具有不同自定义端口的SSH连接时,这是否是必要的路由? - Martin Braun

7
这可以通过使用-P选项指定端口来实现:
scp -i ~/keys/yourkey -P2222 file ubuntu@host:/directory/

6

scp帮助文档告诉我们,端口需要使用大写字母P进行指定。

~$ scp
usage: scp [-12346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]
           [-l limit] [-o ssh_option] [-P port] [-S program]
           [[user@]host1:]file1 ... [[user@]host2:]file2

希望这可以帮到您。

5
scp -P 22 -r DIR  huezo@192.168.1.100:/home/huezo

scp -P PORT -r DIR  USER@IP:/DIR

你的答案可以通过添加更多关于代码的信息以及它如何帮助提问者来改进。 - Tyler2P

4

如果你需要将本地文件复制到服务器(指定端口)

scp -P 3838 /the/source/file username@server.com:/destination/file

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接