当使用 SSH 将 rsync 连接到远程服务器时,如何转义远程路径中的空格等?一个简单的反斜杠就可以转义本地 bash 提示符中的空格,但在远程计算机上,空格会被读取为路径中的中断,从而标记该路径的结束。
因此,当我这样做时,远程服务器正在读取它,因为它无法远程找到该目的地,因为实际目的地是“某个目录”而不仅仅是“某个”。rsync -avz /path/to/source/some\ dir/ [email protected]:/path/to/dest/some\ dir/
/path/to/dest/some/
如果我尝试相同的命令并转义反斜杠和空格以越过本地 bash 提示符并为远程服务器维护反斜杠(总共三个反斜杠:)/path/to/dest/some\\\ dir/
,它确实会将反斜杠发送到远程服务器,但远程服务器随后将路径解释为/path/to/dest/some\/
而不是/path/to/dest/some\ dir/
仍然剥离空格和其后的字符。
如果我尝试用引号括起路径,它的行为几乎相同,实际上在空格处切断路径。因此它也只能绕过本地 bash 提示符。
最初,我使用的路径中包含“ - ”(空格-连字符-空格)段,而远程服务器返回了一个错误,rsync: on remote machine: -: unknown option
这正是启动整个空格转义过程的根本原因。
那么我必须做什么才能让它与远程服务器正常工作,而不必从远程路径中删除空格或其他错误字符(如连字符)?
答案1
在启动器计算机上,rsync
建立一个命令行,调用远程计算机上的 rsync 目标,然后使用 ssh 发送该命令行....作为单个字符串。该单个字符串被传递给 shell 进行解析、拆分为参数并执行rsync
。我不知道为什么要这样做,而不是将(已经拆分、扩展和取消引用的)参数打包到某个二进制安全容器中并发送到远程 rsync。
这意味着你的论点将被解析二不同的外壳,引用和重新报价因此。通常,我会用双引号将每个参数括起来,然后将整个表达式括在单引号中。有时这还不够,或者如果您希望在本地和远程使用相同的表达式,则可能会很复杂。
在这种情况下,我通常会设置一些具有简单、无空格、全 ASCII 名称的软链接,并使用它。
答案2
问题:
rsync 通过 ssh 使用两枚贝壳运行:一个本地,一个远程。参数
[email protected]:/path/to/dest/some\ dir/
首先由本地 shell 解释。因此,它变为[email protected]:/path/to/dest/some dir/
。这是传递给远程 shell 的值,远程 shell 会(当然)将其解释为两个单独的参数:[email protected]:/path/to/dest/some
和dir/
。
重点答案:
不需要任何花招就能得到想要的结果。rsync 内置了解决方案(除非你使用的是某个古老的版本):
-s, --protect-args no space-splitting; only wildcard special-chars
因此,如果添加该-s
标志,则仅需为本地 shell 引用您的参数:
rsync -savz user@server:"/my path with spaces/another dir/" "/my destination/"
答案3
当您说出以下话时,您说的是对的:
如果我尝试相同的命令并转义反斜杠和空格以越过本地 bash 提示符并维护远程服务器的反斜杠
这是我发现的最简单的方法:
rsync -av dir\ with\ spaces/ server.tld:"dir\ with\ spaces"
这种方法同样有效。
rsync -av dir\ with\ spaces/ server.tld:dir\\\ with\\\ spaces
您可以发布确切的输出以及您看到的任何错误吗?
您能用rsync
包装脚本替换两边吗?
$ sudo su -
# cd /usr/bin
# mv rsync rsync.real
# cat <<'EOF' >rsync
#!/bin/bash
logfile=/home/yourname/rsync.log
date >> "$logfile"
i=1
for arg in "$@"; do
echo "arg $i: $arg" >> "$logfile"
i=$((i+1))
done
rsync.real "$@"
EOF
# chmod +x rsync
然后再次运行 rsync,它应该证明这种转义方式有效,例如
客户端:
Sun Feb 13 13:48:12 EST 2011
1: -av
2: dir with spaces/
3: server:dir\ with\ spaces
服务器端:
Sun Feb 13 13:48:13 EST 2011
1: --server
2: -vlogDtpre.iL
3: .
4: dir with spaces
在上面的例子中,服务器上的第 4 个参数(dir with spaces
)都在一行上,这说明引用工作正常。
如果这没有帮助,请尝试重新运行rsync -v
、 或rsync -vv
或rsync -vvv
。它将为您提供额外的调试信息。
另外两个愚蠢的建议:
- 另一台服务器是 Linux 服务器吗?那里的默认 shell 是什么?
- 也许它的文件名扩展方式与你预期的不同
- 您忘记添加
-a
或-r
选项了吗?- 如果不看你的输出,我无法判断
答案4
您只需将路径括在引号中即可。