如何在scp中转义&符号

10

我知道有很多人问过如何在scp中转义空格的问题,但是我试图使用“&”符号却失败了,如果这个符号是目录名称的一部分。

[sorunome@sorunome-desktop tmp]$ scp test.txt "bpi:/home/sorunome/test & stuff"
zsh:1: command not found: stuff
lost connection

&符号似乎会混淆很多东西,使用\&无法解决问题,因为远程目录找不到:

[sorunome@sorunome-desktop tmp]$ scp test.txt "bpi:/home/sorunome/test \& stuff"
scp: ambiguous target

即使省略引号并在各处添加 \ ,这也无法正常工作:

[sorunome@sorunome-desktop tmp]$ scp test.txt bpi:/home/sorunome/test\ \&\ stuff
zsh:1: command not found: stuff
lost connection

那么,有什么想法吗?


你必须使用zsh吗?我在bash下尝试过,而且没有任何额外的转义也可以工作。 - Aaron
不,我不必使用zsh,我只是用bash尝试了一下,效果相同(而不是它显示“zsh:1”,现在它显示“bash”)另外,因为你很感兴趣,我刚刚尝试了 scp test.txt "bpi:/home/sorunome/test & touch test.tmp", 它实际上会在我的远程主目录中创建test.tmp文件! - Sorunome
5个回答

14

对我而言,同时转义空格和&符号解决了问题:

scp source_file "user@host:/dir\ with\ spaces\ \&\ ampersand"

由于某些原因,引号仍然是必需的。


1
奇怪,这似乎有效!不过你有什么想法如何将其添加到Bash脚本的变量中吗? - Sorunome
这似乎可以实现:scp "$(sprintf %q "$local")" "$(sprintf %q "$remote")" - Sorunome
5
引号是用来保护反斜杠本身的。scp有点棘手,因为参数会被处理两次:在运行scp之前由本地Shell处理一次,然后在文件名发送到远程主机后再处理一次。 (可以将scp看作是类似于cat source_file | ssh user@host 'cat > "/dir with spaces & ampersand"'的包装器。) - chepner

0

这是对我有效的方法:

function escape_file() {
    local ESCAPED=$(echo "$1" | sed -E 's:([ ()[!&<>"$*,;=?@\^`{}|]|]):\\\1:g' | sed -E "s/([':])/\\\\\1/g")
    echo "$ESCAPED"
}
REMOTE_FILE="/tmp/Filename with & symbol's! (xxx) [1.8, _aaa].gz"
scp "server:$(escape_ "$REMOTE_FILE")" /tmp/

你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

0

如果你需要转义 %,请使用 %%


0

使用scp或cp时,特殊字符可能会破坏文件路径。您可以通过转义特殊字符来解决这个问题。

使用cp时,您可以使用常规的转义特殊字符方法,在特殊字符前加上反斜杠。例如,带有空格的路径可以使用以下命令进行复制:

cp photo.jpg My\ Pictures/photo.jpg

在scp中,远程路径不适用于此方法。您需要使用双反斜杠转义特殊字符。使用相同的示例,My Photos文件夹将使用以下方式转义其空格:

scp photo.jpg "user@remotehost:/home/user/My\\ Photos/photo.jpg"

双引号也很重要,必须用双引号括起来包含特殊字符的整个路径。

来源:https://dominichosler.wordpress.com/2011/08/27/using-scp-with-special-characters/


0

将文件名用额外的一对\"括起来,就像这样:

scp "test.txt" "bpi:/home/sorunome/\"test & stuff\""

由于文件名内部不需要更改,因此可以直接应用于变量:

scp "$local" "bpi:/home/sorunome/\"$remote\""

外层引号(")由本地 shell 解释。内层引号(\")在远程服务器上解释。感谢 @chepner 指出参数被处理两次的方式。


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