通过远程 SSH 连接使用 rsync 时在远程路径中转义空格

pur*_*ion 10 ssh bash rsync remote path

当使用 SSH 将 rsync 连接到远程服务器时,如何在远程路径中转义空格等?一个简单的反斜杠转义本地 bash 提示符的空间,但在远程机器上,该空间被读取为路径中的中断,从而标记该路径的结尾。

因此,当我这样rsync -avz /path/to/source/some\ dir/ user@host.tld:/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,这是整个空间转义努力的开始。

那么我必须做些什么才能使远程服务器正常工作,而不必从远程路径中删除空格或其他错误字符(如连字符)?

Jav*_*ier 9

在发起方机器上,rsync建立一个命令行来调用远程机器上的 rsync 目标,然后使用 ssh....作为单个字符串发送该命令行。该单个字符串被传递给 shell 进行解析、拆分为参数并执行rsync。我不知道为什么要这样做,而不是将某些二进制安全容器中的(已经拆分、扩展和未加引号的)参数打包到远程 rsync。

这意味着,你的论点会被解析2个不同的壳,报价重新报价相应。通常,我用双引号将每个参数括起来,然后将整个表达式用单引号括起来。有时这还不够,或者如果您希望在本地和远程使用相同的表达式,则可能会很复杂。

在这种情况下,我通常会使用简单的、无空格的、全 ASCII 名称设置一些软链接,然后使用它。

  • 获胜者是……单引号+双引号!也许这在每台服务器上都不同,所以如果其他答案对某些人不起作用,也许这个答案会起作用。这是我在 rsync 命令的远程端使用的成功代码:`'user@host.tld:"/path/to/dest/some\dir/"'` (8认同)

小智 9

问题:

通过 ssh 进行 rsync 使用两个 shell来运行:一个是本地 shell,一个是远程 shell。该参数 user@host.tld:/path/to/dest/some\ dir/首先由本地 shell 解释。因此,就变成了user@host.tld:/path/to/dest/some dir/。这是传递给远程 shell 的值,它(当然)会将其解释为两个单独的参数:user@host.tld:/path/to/dest/somedir/


重点回答:

不需要任何花招就能得到想要的结果。rsync 具有内置的解决方案(除非您使用的是一些古老的版本):

 -s, --protect-args          no space-splitting; only wildcard special-chars
Run Code Online (Sandbox Code Playgroud)

因此,如果添加该-s标志,则只需要为本地 shell 引用参数:

rsync -savz user@server:"/my path with spaces/another dir/" "/my destination/"
Run Code Online (Sandbox Code Playgroud)