我的问题几乎和下面的完全一样关联,除非我的 ssh 服务器在 docker 容器中。
我的Dockerfile 非常简单。
FROM ubuntu:12.04
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get install -y openssh-server less nano
RUN mkdir /var/run/sshd
RUN adduser chrome
RUN echo "chrome:chrome" | chpasswd
RUN echo "root:chrome" | chpasswd
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
当我尝试 ssh 登录时,它会一直挂起并启动 shell。
$ ssh -p2222 chrome@localhost /bin/bash --noprofile --norc # trying to login with ssh
chrome@localhost's password: <-------------hangs forever
如果我在 ssh 上使用参数,我可以登录-t
。我不知道为什么。
运行其他程序都ls
没有问题。也许有人可以复制这个容器并找出问题所在?
答案1
这与 docker 无关,当您 ssh 到远程主机时也会发生同样的事情。
问题的线索在 ssh 手册页中
-t 强制分配伪 tty。这可用于在远程计算机上执行任意基于屏幕的程序,这非常有用,例如在实现菜单服务时。多个 -t 选项强制分配 tty,即使 ssh 没有本地 tty。
因此,如果您提供要运行的远程命令,除非您使用开关,否则 ssh 不会使用 tty 分配-t
。由于 bash 是交互式的,因此它需要 tty。
答案2
下面不会挂
$ ssh -p2222 chrome@localhost /bin/bash -i --noprofile --norc
需要 bash选项-i
才能获得交互的壳。
摘自 Bash 参考手册1.2 什么是shell?部分:
Shell 可以以交互或非交互方式使用。在交互模式下,它们接受从键盘输入的输入。在非交互模式下,Shell 执行从文件读取的命令。
交互式 shell 是无需非选项参数启动的 shell,除非指定了 -s,且未指定 -c 选项,并且其输入和错误输出均连接到终端(由 isatty(3) 确定),或者使用 -i 选项启动的 shell。
交互式 shell 通常从用户终端读取数据并向用户终端写入数据。
答案3
我发现这个问题是因为我尝试仅通过 sshssh -p 2222 chrome@localhost
进入本地容器,但使用相同的挂起终端时,此方法不起作用。在我切换到 WSL 终端而不是 cygwin 之前,所有建议的解决方案(包括-t
或添加/bin/bash --noprofile --norc
或)/bin/bash -i --noprofile --norc
都不起作用。ssh -p 2222 chrome@localhost
现在可以正常工作,看起来这是 cygwin 的问题。也许这也可以帮助某些人。
答案4
当您启动一个容器时,docker run
您必须指定-it
一个交互式终端,原因与上面解释的完全相同。
作为您的观察,如果您不想明确使用,dockerfile
您可以添加--net=host
到您的命令中,以便容器可以访问本机 NIC 配置。docker run
EXPOSE 22
另外,(虽然听起来很蠢,但我知道)我在使用 docker 登录时遇到了问题,即使是在本地容器上,出现挂起但如果我只是点击<enter>
我就会得到提示......