为什么在传递 SCP 文件名时需要转义空格?

Tha*_*tos 6 scp

任何曾经使用过 SCP 的人都知道这可能行不通:

scp foo.txt 'me@remote.net:foo bar.txt'
Run Code Online (Sandbox Code Playgroud)

对于我来说,我得到:“模糊的目标”。

SCP 的手册页没有解释为什么需要转义该空间,但该参数似乎符合手册页中列出的该参数的规范:

[[user@]host1:]file1 
Run Code Online (Sandbox Code Playgroud)

对我来说似乎很匹配。那么,为什么需要这样做:

scp foo.txt 'me@remote.net:foo\ bar.txt'
Run Code Online (Sandbox Code Playgroud)

Dan*_*eck 11

在第一种情况下,您将两个文件指定为复制目标,都驻留在remote.net. 这显然是模棱两可的,因为程序无法确定将文件复制到何处。

考虑以下使用相同格式指定两个源文件和一个目标(目录)的工作示例:

scp 'me@example.org:file1 file2' .
Run Code Online (Sandbox Code Playgroud)

这将复制两个 file1,并file2example.org本地目录。


您的本地scp程序连接到远程主机,并scp使用一个参数启动另一个实例,该参数确定您是它 ( -f) 还是它 ( -t)传输文件。当您-v为详细输出添加参数时,您可以看到这一点。您输入的源/目标参数 ( host:file) 被拆分,文件名部分只是附加为指定要使用的文件的附加参数。

将其用作源时

debug1: Sending command: scp -v -f -- file1 file2
Run Code Online (Sandbox Code Playgroud)

这没有问题,它可以通过网络传输多个源文件。

将其用作接收器时

debug1: Sending command: scp -v -t -- file1 file2
Run Code Online (Sandbox Code Playgroud)

这失败了,因为您打算写入多个文件。现在解决这个问题的办法是逃避的文件名再次(本地壳一次,一次远程调用):

$ scp foo 'me@example.org:foo\ bar'
[...]
debug1: Sending command: scp -v -t -- foo\\ bar
Run Code Online (Sandbox Code Playgroud)

FWIWscp foo 'me@example.org:"foo bar"'也一样。