为什么“docker附加”挂?

我可以成功运行一个ubuntu容器:

 # docker run -it -d ubuntu 3aef6e642327ce7d19c7381eb145f3ad10291f1f2393af16a6327ee78d7c60bb # docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3aef6e642327 ubuntu "/bin/bash" 3 seconds ago Up 2 seconds condescending_sammet 

但执行docker attach挂起

 # docker attach 3aef6e642327 

直到我按任何键,如Enter

 # docker attach 3aef6e642327 root@3aef6e642327:/# root@3aef6e642327:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var 

为什么docker attach

更新

看完评论后,我想我可以得到答案:

先决条件:

“docker附加”重复使用相同的tty,而不是打开新的tty。

(1)在没有守护进程模式下执行docker run

 # docker run -it ubuntu root@eb3c9d86d7a2:/# 

一切正常,然后运行ls命令:

 root@eb3c9d86d7a2:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var root@eb3c9d86d7a2:/# 

(2)以守护进程模式运行docker run

 # docker run -it -d ubuntu 91262536f7c9a3060641448120bda7af5ca812b0beb8f3c9fe72811a61db07fc 

实际上, 下面的内容应该从运行的容器输出到stdout:

 root@91262536f7c9:/# 

所以执行docker attach似乎挂起,但实际上它正在等待您的input:

 # docker attach 91262536f7c9 ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var root@91262536f7c9:/# 

Solutions Collecting From Web of "为什么“docker附加”挂?"

它并不真正挂起 。 正如你可以在下面的注释中看到的(你正在运行“ /bin/bash ”作为命令),它似乎是附加的预期行为。

据我了解,你附加到正在运行的shell,只是stdin /标准输出/标准错误 – 根据你传递给运行命令的选项 – 只会告诉你任何进出的那一刻 。 (有些更深入的知识可以在更高的层面上解释这一点)。

正如我在对你的问题的评论中写到的,有几个人在docker github repo上打开了一个问题,描述了类似的行为:

  • 码头附加[容器]挂起,需要输入#8521
  • 附加到容器时,码头附加设置挂起设置终端状态

既然你提到shell,我假设你已经有一个shell正在运行。 attach不会启动一个新的进程,那么连接到正在运行的进程的in /​​ out / err流的预期行为是什么? 我没有想到这一点。 当然这是附加到正在运行的shell的预期行为,但它是可取的吗?

是否可以在docker attach上刷新stdout / stderr,从而强制shell提示符被打印,还是比这更复杂? 这就是我个人在连接到一个已经运行的shell时会“期望”的东西。

如有必要,请随时关闭此问题,我只是觉得有必要记录这一点,并得到一些反馈。

  • 采取从这个github问题的评论 。 你可以在这个问题的评论中找到更多的见解。

如果不是enter你会开始输入一个命令,你不会看到额外的空提示行。 如果你要跑步

 $ docker exec -it ubuntu <container-ID-or-name> bash 

在你运行docker run -it docker run -it -d ubuntu (在你的问题中是3aef6e642327或condescending_sammet)之后, <container-ID-or-name>是容器的ID或名称,它会运行一个新的命令,因此不会有这个“stdout问题“附加到现有的一个。

如果你在一个包含以下内容的目录中有一个Dockerfile

 FROM ubuntu:latest ADD ./script.sh /timescript.sh RUN chmod +x /timescript.sh CMD ["/timescript.sh"] 

在同一目录下有一个简单的bash脚本script.sh ,其中包含:

 #!/bin/bash #trap ctrl-c and exit, couldn't get out #of the docker container once attached trap ctrl_c INT function ctrl_c() { exit } while true; do time=$(date +%N) echo $time; sleep 1; done 

然后构建(在本例中与Dockerfile和script.sh相同的目录)并运行它

 $ docker build -t nan-xiao/time-test . ..stuff happening... $ docker run -itd --name time-test nan-xiao/time-test 

最后attach

 $ docker attach time-test 

您将最终连接到每秒打印时间的容器。 (CTRL-C出去)

例2

或者,如果你有一个Dockerfile包含例如以下内容:

 FROM ubuntu:latest RUN apt-get -y install irssi ENTRYPOINT ["irssi"] 

然后运行在同一个目录下:

 $ docker build -t nan-xiao/irssi-test . 

然后运行它:

 $ docker run -itd --name irssi-test nan-xiao/irssi-test 

最后

 $ docker attach irssi-test 

如果没有这种特殊行为,你最终会在一个正在运行的irssi窗口中运行。 当然,你可以用irrsi替换另一个程序。

这发生在我身上,原因如下:

这可能是容器内的bash命令正在执行“cat”命令。

所以当你附加到容器(bash命令)时,你实际上是在期待输入的cat命令中。 (文本和/或ctrl-d来写入文件)

如果你不能访问命令行,只要确保你在启动时用-i标志运行你的容器。

当试图附加到由其他人开发并已经运行守护进程的容器时,我遇到了这个问题。 (在这种情况下,这是Linuxserver的transmission泊坞镜像)。

问题:

发生了什么事是终端似乎'挂',打字什么都没有帮助,不会出现。 只有Ctrl-C会把我踢出去。

docker rundocker startdocker attach一切都没有成功,事实证明我需要的命令(容器已经开始runstart )是执行bash ,因为你从中拉出的容器没有bash已经运行。

解:

docker exec -it <container-id> bash

(你可以从运行的docker ps -a找到container-id )。

这将把你带入一个功能性bash的实例(假设你没有其他显式的设置)。

我知道已经接受的答案已经把这个问题解决了,但是决定发表一个更简洁明了的答案,因为当我读这个答案的时候,解决方案并没有出现。