我可以成功运行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 attach”重用相同的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
似乎挂了,但实际上它正在等待你的输入:
# 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:/#
它并没有真正挂起。正如您在下面的注释中所看到的(您正在运行“/bin/bash
”作为命令),它似乎是附加时的预期行为。
据我所知,你附加到正在运行的shell,只是stdin / stdout / stderr - 取决于你传递的选项和运行命令 - 将只显示从那一刻进出的内容。 (有更多深入知识的人希望能够在更高层次上解释这一点)。
正如我在你对你的问题的评论中写的那样,有几个人在docker github repo上打开了一个描述类似行为的问题:
既然你提到了shell,我假设你已经运行了一个shell。 attach不会启动新进程,那么连接到正在运行的进程的in / out / err流的预期行为是什么?我没想到这个。当然这是连接到正在运行的shell的预期行为,但它是否可取?
是否可以在docker attach上刷新stdout / stderr,从而强制打印shell提示符,或者它是否比这更复杂?这是我个人在连接到已经运行的shell时“期望”的东西。
如有必要,请随时关闭此问题,我只是觉得有必要记录下来并获得一些反馈。
如果不是enter
而是开始键入命令,则不会看到额外的空提示行。如果你要跑
$ docker exec -it ubuntu <container-ID-or-name> bash
其中<container-ID-or-name>
是运行docker run -it -d ubuntu
后容器的ID或名称(在你的问题中为3aef6e642327或condescending_sammet)它将运行一个新命令,因此没有附加到现有的“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退出)
或者,如果你有一个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
替换另一个程序。
当我尝试连接到由其他人开发并已经运行守护进程的容器时,我也遇到了这个问题。 (在这种情况下,它是LinuxServer的transmission
docker图像)。
发生的事情是终端似乎“挂起”,输入任何东西都没有帮助,也不会出现。只有Ctrl-C
会把我踢回去。
docker run
,docker start
,docker attach
都没有成功,结果我需要的命令(在容器已经启动run
或start
之后)执行bash
,因为你从中取出的容器没有bash已经运行。
docker exec -it <container-id> bash
(你可以从运行container-id
找到docker ps -a
)。
这将使用功能bash作为root
将您带入实例(假设您提取的图像没有进行其他显式设置)。
我知道接受的答案也已经捕获了这个,但是我决定发布另一个更简洁明了的答案,因为当我阅读它时,解决方案并没有突然出现。
由于以下原因,这件事发生在我身上:
可能是容器内的bash命令正在执行“cat”命令。
所以当你附加到容器(bash命令)时,你实际上是在cat命令中,它正在期待输入。 (文本和/或ctrl-d写入文件)
当我运行docker attach container-name
,然后没有输出,甚至Ctrl-c
无效。所以,先试试
docker attach container-name --sig-proxy=false
然后ctrl-c
可以阻止它。为什么它没有输出任何东西?只是因为容器没有输出。实际上我需要输入我的容器并运行一些shell命令。所以正确的命令是
docker exec -ti container-name bash
如果您无法访问命令行,请确保在开始时使用-i
标志运行容器。
以下是我发生的事情:
docker-compose logs -f nginx
Attaching to laradock_nginx_1
然后它会挂在那里直到我通过CTRL-C退出:^CERROR: Aborting.
docker ps -a
表明应该被称为laradock_nginx
的那个图像名称不存在,所以我想我只是删除并重新“填充”该容器:
docker stop cce0c32f7556
docker rm cce0c32f7556
docker-compose up -d laradock_nginx
不幸的是:ERROR: No such service: laradock_nginx
所以我做了sudo reboot
然后docker ps -a
,但laradock_nginx
仍然没有。
幸运的是,docker-compose up -d nginx
然后工作,docker-compose logs -f nginx
现在工作。