昨天我可以sftp
在 RHEL 5.4 盒子 (RedHat) 上执行此操作,但今天却不能了。
消息是"Received message too long 778199411"
,经过一番调查,这是因为我的 RHEL 盒子.bashrc
有一条线echo "running .bashrc"
——或者回显任何东西,我想。
那么为什么打印出一行会产生影响呢sftp
?这感觉有点像一个设计问题,因为.bashrc
在其他情况下(例如登录或)打印出一行,并且当由于如此奇怪的原因而失败ssh
时很难追踪。sftp
所以问题是,为什么打印出一行会导致这样的错误,如果我们仍然想打印出一些东西怎么办.bashrc
? (主要是查看该文件何时获取/执行)。
答案1
这是一个长期存在的问题。十年前,当我第一次不得不在工作中混合使用商业 SSH 和在家中使用开放 SSH 时,我就发现了这一点。今天又遇到这个问题,发现了这个帖子。
如果我搜索“sftp/scp 失败但 ssh 正常”,我会更快收到解决方案提醒!
简而言之,.bashrc
、.bash_profile
、.cshrc
、.profile
等对于非交互式会话必须保持静默,否则它们会干扰 sftp/scp 连接协议。
此输出使 sftp/scp 客户端感到困惑。您可以通过执行以下命令来验证您的 shell 是否正在执行此操作:SSH你的主机/usr/bin/true如果上述命令产生任何输出,则您需要修改 shell 初始化。
来自 open-SSH 常见问题解答: 2.9 - sftp/scp 连接失败,但 ssh 正常。
答案2
至少对于 SFTP 来说,这可以通过使用internal-sftp
子系统来修复,因为它不读取.bashrc
或/etc/motd
。
只需更改/etc/ssh/sshd_config
文件并更改 SFTP 子系统:
#Subsystem sftp /usr/lib/openssh/sftp-server
Subsystem sftp internal-sftp
错误消失了。
答案3
如果该 id 使用 bash,只需将以下内容放入远程计算机上 id 用户名的 ~/.bashrc 顶部
# If not running interactively, don't do anything and return early
[[ $- == *i* ]] || return
它只是从 ~/.bashrc 提前退出,而不是获取整个文件...这解决了当您没有登录该 id 并且只是使用该用户名作为远程 id 运行 scp 或 sftp 时使 .bashrc 保持沉默...在其他答案中引用@Peter Scott:“简单地说,.bashrc 和 .bash_profile 等必须保持沉默,否则它们会干扰 sftp / scp 连接协议。”
或者,如果该远程 ID 使用 zsh,则将以下内容放在其 ~/.zshrc 顶部
# If not running interactively, don't do anything and return early
[[ -o interactive ]] || exit 0
如果远程计算机上的 shell 不使用 ~/.bashrc,则在文件 ~/.bashrc_profile 或 ~/.profile 或类似文件中进行上述编辑,以适合该远程机器上的 shell
....更新...通过将上面的代码片段放入远程主机上的用户的文件 ~/.bashrc 顶部,任何 ssh 连接都将源文件 ~/.bashrc ,该文件将简单地读取 ~/.bashrc 直到看到此代码片段,然后停止继续获取其余部分文件 ~/.bashrc 以避免用 ssh 连接不需要也不想要的东西污染远程机器上的 shell ... 不要将代码片段放入任何必须获取或执行完成的文件中,作为此代码片段的点是从源文件 ~/.bashrc 中提前退出(注意,源文件与执行文件之间存在差异)...文件 ~/.bashrc 始终是源文件,从未执行
答案4
可能还有一个原因。在带有 openssh-5.3p1-122.el6.x86_64 的 RHEL 6 上,我们发现,当 LOCALE 保持在“C”时,它的行为是错误的。当更改为:
export LC_ALL="en_US.UTF-8"
然后 sftp 行为正确。在之前的 openssh-5.3p1-118 中,我们没有遇到过这样的行为,因此这可能是此版本中的一些小错误。