是的,我知道你在想什么:“到底是谁给他们的文件命名的`a`b
?”
但让我们假设你做有一个名为`a`b
(可能是由疯狂的 Mac 用户创建的 - 显然不是您创建的)的文件,并且您想要rsync
该文件。显而易见的解决方案:
rsync server:'./`a`b' ./.;
rsync 'server:./`a`b' ./.;
给出:
bash: line 1: a: command not found
rsync: [sender] link_stat "/home/tange/b" failed: No such file or directory (2)
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1865) [Receiver=3.2.7]
rsync: [Receiver] write error: Broken pipe (32)
甚至:
$ rsync 'server:./\`a\`b' ./.;
bash: line 3: a\: command not found
rsync: [sender] link_stat "/home/tange/\b" failed: No such file or directory (2)
:
是什么rsync
我的命令应该正在跑步?
$ rsync --version
rsync version 3.2.7 protocol version 31
答案1
手动二分后,这是 rsync 中的一个错误,已通过以下方式修复commit 5c93dedf4538(“向 SHELL_CHARS 添加反引号。”),它将出现在即将发布的 rsync 3.2.8(尚未发布)中。它被打破了commit 6b8db0f6440b(“使用反斜杠转义添加 arg 保护习惯用法”),位于 3.2.4 中。
作为缓解措施,存在使用旧 arg 解析行为 ( ) 的选项--old-args
:
rsync --old-args 'server:./\`a\`b' .
答案2
是版本问题。似乎不取决于服务器版本,而是取决于客户端。
v3.2.3 和 v3.2.7 之间出现了一些问题。
好的:
$ rsync-v3.2.3 --rsync-path=rsync-v3.2.7 'server:./\`a\`b' ./.;
$ rsync-v3.2.3 --rsync-path=rsync-v3.2.3 'server:./\`a\`b' ./.;
$ rsync-v3.2.3 --rsync-path=rsync-v3.2.3 server:./"'"'`a`'"'"b ./.;
失败:
$ rsync-v3.2.7 --rsync-path=rsync-v3.2.7 'server:./\`a\`b' ./.;
bash: line 3: a\: command not found
rsync: [sender] link_stat "/home/tange/\b" failed: No such file or directory (2)
$ rsync-v3.2.7 --rsync-path=rsync-v3.2.3 'server:./\`a\`b' ./.;
bash: line 3: a\: command not found
rsync: [sender] link_stat "/home/tange/\b" failed: No such file or directory (2)
$ rsync-v3.2.3 --rsync-path=rsync-v3.2.3 'server:./`a`b' ./.;
bash: line 1: a: command not found
rsync: [sender] link_stat "/home/tange/b" failed: No such file or directory (2)
$ rsync-v3.2.3 --rsync-path=rsync-v3.2.7 'server:./`a`b' ./.;
bash: line 1: a: command not found
rsync: [sender] link_stat "/home/tange/b" failed: No such file or directory (2)
但说真的:这似乎是一场即将发生的灾难,你需要引用`
两次。
感谢@dhag 指出这个问题。
不幸的是,它没有回答如何使用 v3.2.7 版本进行传输。
答案3
如果您不必支持rsync
3.0.0 之前的版本,请使用--secluded-args
aka -s
(以前称为 )--protect-args
,然后您不必担心远程用户的登录 shell(可能是任何内容)如何解释文件名,因此在通过 rsh/ssh 进行 rsync 时,正确地进行引用/转义几乎是不可能的。从手册(3.2.7):
--secluded-args, -s This option sends all filenames and most options to the remote rsync via the protocol (not the remote shell command line) which avoids letting the remote shell modify them. Wildcards are ex‐ panded on the remote host by rsync instead of a shell. This is similar to the default backslash-escaping of args that was added in 3.2.4 (see --old-args) in that it prevents things like space splitting and unwanted special-character side-ef‐ fects. However, it has the drawbacks of being incompatible with older rsync versions (prior to 3.0.0) and of being refused by restricted shells that want to be able to inspect all the option values for safety. This option is useful for those times that you need the argu‐ ment's character set to be converted for the remote host, if the remote shell is incompatible with the default backslash-escpaing method, or there is some other reason that you want the majority of the options and arguments to bypass the command-line of the remote shell. If you combine this option with --iconv, the args related to the remote side will be translated from the local to the remote character-set. The translation happens before wild-cards are expanded. See also the --files-from option. You may also control this setting via the RSYNC_PROTECT_ARGS en‐ vironment variable. If it has a non-zero value, this setting will be enabled by default, otherwise it will be disabled by de‐ fault. Either state is overridden by a manually specified posi‐ tive or negative version of this option (note that --no-s and --no-secluded-args are the negative versions). This environment variable is also superseded by a non-zero RSYNC_OLD_ARGS export. This option conflicts with the --old-args option. This option used to be called --protect-args (before 3.2.6) and that older name can still be used (though specifying it as -s is always the easiest and most compatible choice).