如何使用scp传输文件名中包含冒号的文件?

60

我正在尝试使用bash中的scp复制一个在源文件名中包含冒号(:)字符的文件。我正在使用混淆版本的命令:

scp file\:\ name.mp4 user@host:"/path/to/dest"

我遇到了这个错误:

ssh: Could not resolve hostname Portal 2: Name or service not known
我知道我可以重命名文件并删除冒号,但我想知道是否有可能转义冒号。
2个回答

112

这不完全是一个 bash 转义问题,而是 scpx: 视为 [user@]host 前缀,请尝试:

scp ./file:\ name.mp4 user@host:"/path/to/dest"

使用相对路径(例如./)或完全限定路径(/path/to/source)可以防止这种行为 - 在:之前存在/会导致OpenSSH停止检查可能的host:user@host:前缀。 OpenSSH的scp仅特殊处理以冒号开头的文件名,使其无需问题即可工作,它没有支持以正常方式转义:的功能,并且没有其他有效主机名的概念,因此几乎任何带有:的文件名都可能导致此问题(或在[ ]:之前找到时等效的IPv6行为)。 这也会影响其他程序,例如rsync,同样的解决方法适用于那里。 (由于OpenSSH对[]封装的IPv6地址的简单解析,您可以成功地scp包含以[开头的:或包含@ [的文件::之前,不包含]:,但通常没有用;-)
The following text was written when the original question was "How do I escape a colon in bash?" It applies to that situation, but not to scp as no amount of shell escaping will help there. To answer the question about how to escape :, you don't need to, but "\:" works. Places that a : is used:
1. 空命令:,不需要转义,虽然可以,就像\e\c\h\o foo一样,它对命令没有影响(“没有影响”并不完全正确,如果你转义一个或多个字符,它将防止别名被匹配,并且你可以给:起别名)。 2. PATH(和其他的,如CDPATHMAILPATH),转义这些值没有任何有用的效果(我无法从包含:的目录中运行我的PATH中的程序,这有点出乎意料)。 3. 参数扩展${name:-x}等,name必须是[a-zA-Z_][a-zA-Z0-9_],所以不需要转义变量名,并且由于没有歧义,在参数扩展的其他变体中也不需要转义后面的:。 4. ? :三元操作只作用于变量和数字,不需要转义。 5. 在模式中带有类似[[:digit:]]的类时,===~,你可以用\:转义,但我不知道那有什么用...... 6. 在命令或函数名称中,不需要转义,\:没有任何有用的效果。
(注意,空命令只是:,您可以拥有一个命名为“:foo”的命令或函数,并且可以在不转义的情况下调用它,在这方面它与#不同,其中命名为#foo的命令需要转义。)

1
同样的问题也会影响到 rsync。幸运的是,同样的解决方案——在文件名前加上 ./ ——也可以帮助解决这个问题。 - Mikhail T.
三进制 :) 还是三元? - Eric

2

我尝试使用@mr.spuratic的完全限定路径作为最初的回答,但是没有起作用,而在我的情况下,我必须使用绝对路径,这是我的解决方案:

scp `hostname`:/root/this/is/test/file.txt user@host:"/path/to/dest"

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