SSH命令执行挂起,尽管交互式shell功能正常。

31
当我尝试使用SSH在远程服务器上执行命令时,SSH命令会在exec request accepted调试信息后挂起,并最终超时。

失败的命令:ssh -v -v <username>@<server> uptime(也尝试过echo hello等命令)

debug1: Authentication succeeded (publickey).
Authenticated to <server> (<ip>:22).
debug1: channel 0: new [client-session]
debug2: channel 0: send open
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug2: callback start
debug2: client_session2_setup: id 0
debug2: fd 4 setting TCP_NODELAY
debug1: Sending environment.
debug1: Sending env LANG = en_US.UTF-8
debug2: channel 0: request env confirm 0
debug1: Sending command: uptime
debug2: channel 0: request exec confirm 1
debug2: callback done
debug2: channel 0: open confirm rwindow 0 rmax 32768
debug2: channel 0: rcvd adjust 2097152
debug2: channel_input_status_confirm: type 99 id 0
debug2: exec request accepted on channel 0

它就这样悬着,时间长久。

然而,如果我在没有命令的情况下ssh到远程服务器,我就能得到一个交互式shell,一切都很好。

成功的命令:ssh -v -v <用户名>@<服务器>

输出:

debug1: Authentication succeeded (publickey).
Authenticated to <server> (<ip>:22).
debug1: channel 0: new [client-session]
debug2: channel 0: send open
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug2: callback start
debug2: client_session2_setup: id 0
debug2: fd 4 setting TCP_NODELAY
debug2: channel 0: request pty-req confirm 1
debug1: Sending environment.
debug1: Sending env LANG = en_US.UTF-8
debug2: channel 0: request env confirm 0
debug2: channel 0: request shell confirm 1
debug2: callback done
debug2: channel 0: open confirm rwindow 0 rmax 32768
debug2: channel_input_status_confirm: type 99 id 0
debug2: PTY allocation request accepted on channel 0
debug2: channel 0: rcvd adjust 2097152
debug2: channel_input_status_confirm: type 99 id 0
debug2: shell request accepted on channel 0
Welcome!
<prompt>%
...

有没有人知道为什么交互式会话成功了,但命令执行却不成功?

这个问题困扰我已经几个月了,因为我不能再使用Unison同步我的文件了(以前可以)。非常感谢任何帮助。


我不知道你问题的答案,但我有一个想法。也许你的SSH客户端或SSH服务器存在配置错误。尝试使用不同的客户端连接同一台服务器,然后再尝试使用相同的客户端连接不同的服务器,看看哪个可行。 - pts
一些类似的问题之前已经在stackoverflow上发布过:http://www.google.com/search?q=ssh+command+execution+hangs - James C
这不是SSH配置问题 - 它从不同的客户端失败。服务器配置对我来说是锁定的,但被其他用户验证过。这里发布的其他问题并不完全相同,我已经浏览过它们了。 - Robert Muil
7个回答

33
问题确实是我的登录脚本,尽管与需要终端无关(我已经怀疑并测试了-t-T选项)。问题在于我的.bashrc运行了一个exec(在这种情况下是到zsh的 - 因为我们的系统不允许将chsh更改为zsh)。
有问题的行:
test -f /usr/bin/zsh && exec /usr/bin/zsh

首先检查是否为交互式shell,如果是则退出:

[ -z "$PS1" ] && return
test -f /usr/bin/zsh && exec /usr/bin/zsh

因为 shell 在执行 zsh,所以 ssh 一直在等待执行完成 - 而这个过程从来没有完成。
我有点困惑为什么我的 .bashrc 会被调用 - 我认为这只是针对交互式 shell 的,但各种启动脚本的确切目的和顺序是我永远不会学会的东西。
我希望这对那些在其启动脚本中使用了 exec 的人有所帮助。
顺便说一句 - 另外两个答案都在正确的方向上,所以我完全不确定我是应该 '回答' 还是只评论他们的答案。如果在stackoverflow上回答自己的问题是道德上的错误,请让我知道,我会赎罪的。感谢其他回答者。

1
.bashrc文件在每次调用shell并连接到终端时都会被调用。而.bash_profile文件仅在登录时被调用。这两者之间的区别很模糊,但可以通过执行echo 'echo I am logged in' > ~/.bash_profile命令并使用ssh执行一个命令来轻松检查。这样你就可以看到直接通过ssh执行命令是否使shell成为登录shell。 - Mel
我在使用oh-my-zsh时遇到了完全相同的问题,我不得不在source $ZSH/oh-my-zsh.sh之前插入[ -z "$PS1" ] && return以避免在使用另一个主机作为代理时SSH挂起。 - Kenneth Hoste

6
我们通过添加 -n(将标准输入重定向到 /dev/null)和 -t(强制分配伪终端)解决了这个问题。
例如:
ssh -t -n user@host command

4

你的问题很可能在于你的shell启动或退出脚本。如果不知道里面有什么内容,很难猜测实际问题。


3

我最近遇到了一个具有相同症状的问题,但是确定这个问题并不是我的登录脚本的问题。相反,我的本地.ssh/config文件为我要复制到的主机配置了RequestTTY force


2

在解决其他新问题后,我在Fedora Server 22上遇到了这个问题。

使用-t选项的ssh ziimp /bin/true是可以的,但不是ssh ziimp /bin/true,而且我的git+ssh和scp都被锁定了。

我找到的解决方案在authorized_keys文件中。我必须从我的受信任的密钥中删除command="/usr/bin/bash"前缀...


2

检查您的shell启动文件中的命令(我会从您的提示中假设~/.cshrc;在非交互式会话中,~/.login不重要),这些命令需要终端。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接