事实证明 rsync 无法与具有 .bashrc 文件的远程服务器一起工作?
在本地客户端运行 rsync 时我得到:
protocol version mismatch -- is your shell clean?
(see the rsync man page for an explanation)
rsync error: protocol incompatibility (code 2) at compat.c(180) [sender=3.0.7]
根据建议这里删除服务器上的 .bashrc 解决了问题。如何在不删除 .bashrc 文件的情况下(暂时)解决该问题?
答案1
如果.bashrc
远程服务器上的 向终端输出任何内容,则可能会遇到问题。Rsync 可能没有预料到这一点,因此可能会出现问题。
您可以通过删除输出文本中的任何命令.bashrc
或将任何输出传输到 /dev/null 来解决此问题。
答案2
.bashrc 确实不是生成输出的正确位置,因为它会导致此类问题。不过,许多人都侥幸逃脱了这种惩罚,直到他们尝试运行 rsync :-)
任何所需的输出(以及相关的逻辑和命令)都应移至 .bash_profile(例如,服务器故障问题“.profile 与 .bash_profile 与 .bashrc”以进一步讨论文件之间的差异)。
这样,您就不需要牺牲登录时的输出,也不需要在使用 rsync 时对 .bashrc 进行临时更改。
答案3
问题
为了原因复杂rsync/scp/sftp 在连接到另一台主机时运行 .bashrc。仅仅存在 .bashrc 并不是什么问题。问题出现了如果 .bashrc 中的任何命令在非交互式会话。
适用于大多数情况的好解决方案
将这些命令中的任何一个放置在.bashrc 顶部:
任何一个
# for non-interactive sessions stop execution here -- https://serverfault.com/a/805532/67528
[[ $- != *i* ]] && return
或者
# for non-interactive sessions stop execution here -- https://serverfault.com/a/805532/67528
[ -z "$PS1" ] && return
上述任何命令都只允许在交互式会话中执行其余的 .bashrc 命令。据我所知,在任何其他类型的会话中都不需要它们(事实上,我已经看到 Arch 和 Debian 的默认 bashrc 在其 bashrc 中使用了这种技术)。
针对罕见情况的好解决方案
如果你想要格外谨慎地让 bashrc 命令在非交互式会话中运行,你至少应该包装可能产生输出的命令,如下例所示(参考):
if shopt -q login_shell; then
# this is an interactive session, we _can_ display output
...commands that may produce output goes here...
fi
您可能应该避免的解决方案
其他人建议将输出文本的命令移动到你的 bash_profile 中,但我怀疑这是否总是好的(因为原因解释如下)
答案4
到目前为止,所有答案都假设 shell 存在一些问题,而事实上,问题可能出在协议版本上,正如错误所述。
就我而言,我尝试将文件从 CentOS 7(具有旧的 rsync 2.5.6)rsync 到 Ubuntu 20.04(具有 3.1.2)。
rsync --version
rsync version 2.5.6 protocol version 26
Copyright (C) 1996-2002 by Andrew Tridgell and others
在我将--protocol=26
我的rsync
调用添加到 Ubuntu 之后,一切都同步正常。