为什么 "docker attach" 挂起?
Why does "docker attach" hang?
我可以 运行 一个 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
实际上,以下内容应该从 运行ning 容器输出到标准输出:
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:/#
它并没有真正挂起。正如您在下面的评论中看到的那样(您正在 运行ning "/bin/bash
" 作为命令)这似乎是附加时的预期行为。
据我了解,您附加到 运行ning shell 和 stdin/stdout/stderr - 取决于您随 运行 命令传递的选项 -只会向您展示从那一刻起 in/out 发生的一切 。 (希望有更深入知识的人可以在更高层次上解释这一点)。
正如我在对您的问题的评论中所写,有几个人在 docker github 存储库上提出了一个问题,描述了类似的行为:
- docker attach [container] hangs, requires input #8521
- docker attach hangs setting terminal state when attaching to container
Since you mention shell, I assume you have a shell already running. attach doesn't start a new process, so what is the expected behavior of connecting to the in/out/err streams of a running process?
I didn't think about this. Of course this is the expected behavior of attaching to a running shell, but is it desirable?
是否有可能在 docker attach 上刷新 stdout/stderr 从而强制打印 shell 提示符,还是比这更复杂一些?这就是我个人 "expect" 附加到已经 运行ning shell.
时的情况
如有必要,请随时关闭此问题,我只是觉得有必要记录下来并获得一些反馈。
- 取自comment on this github issue。您可以在本期的评论中找到更多见解。
如果您开始键入命令而不是 enter
,您将不会看到 extra 空提示行。如果你要 运行
$ docker exec -it ubuntu <container-ID-or-name> bash
其中 <container-ID-or-name>
是您 运行 docker run -it -d ubuntu
之后容器的 ID 或名称(因此您的问题中的 3aef6e642327 或 condescending_sammet)它将 运行 new 命令,因此没有附加到现有命令的 "stdout problem"。
例子
如果您在包含以下内容的目录中有一个 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
window。当然,您可以用 irrsi
替换另一个程序。
我遇到过一次,原因如下:
可能是容器内的bash命令正在执行"cat"命令。
因此,当您附加到容器(bash 命令)时,您实际上在 cat 命令中,该命令正在等待输入。 (text and/or ctrl-d写入文件)
如果您无法访问命令行,请确保您 运行 您的容器在启动时带有 -i
标志。
我 运行 在尝试附加到由其他人开发并且已经 运行 一个守护进程的容器时,我也陷入了这个问题。 (在这种情况下,它是 LinuxServer 的 transmission
docker 图像)。
问题:
发生的事情是终端出现在 'hang' 上,在那里输入任何内容都无济于事,也不会出现。只有 Ctrl-C
会把我踢出去。
docker run
、docker start
、docker attach
都没有成功,结果是我需要的命令(在使用 run
或 [=16 启动容器后=]) 是执行 bash
,因为您从中拉出的容器很可能没有 bash 已经 运行.
解决方案:
docker exec -it <container-id> bash
(您可以从 运行 docker ps -a
中找到 container-id
)。
这会将您拉入具有功能 bash 的实例,如 root
(假设您拉取的图像没有完成其他显式设置)。
我知道已接受的答案也包含了这一点,但决定 post 另一个更简洁和明显的答案,因为当我阅读它时,解决方案并没有为我弹出.
当我运行docker attach container-name
时,则没有任何输出,甚至Ctrl-c
也是无效的。所以,先试试
docker attach container-name --sig-proxy=false
然后ctrl-c
可以阻止它。为什么它没有输出任何东西?
只是因为容器没有输出。实际上我需要输入我的容器和 运行 一些 shell 命令。所以正确的命令是
docker exec -ti container-name bash
我今天遇到了类似的问题并且能够解决它:
这是我遇到的情况:
docker-compose logs -f nginx
Attaching to laradock_nginx_1
然后它会挂在那里,直到我通过 CTRL-C 退出:^CERROR: Aborting.
docker ps -a
显示该图像名称不存在应该被称为 laradock_nginx
的内容,所以我想我只是删除并重新 "up" 那个容器:
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
现在起作用了。
使用:docker exec -it CONTAINER_ID/NAME bash
改为:docker attach...
我可以 运行 一个 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
实际上,以下内容应该从 运行ning 容器输出到标准输出:
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:/#
它并没有真正挂起。正如您在下面的评论中看到的那样(您正在 运行ning "/bin/bash
" 作为命令)这似乎是附加时的预期行为。
据我了解,您附加到 运行ning shell 和 stdin/stdout/stderr - 取决于您随 运行 命令传递的选项 -只会向您展示从那一刻起 in/out 发生的一切 。 (希望有更深入知识的人可以在更高层次上解释这一点)。
正如我在对您的问题的评论中所写,有几个人在 docker github 存储库上提出了一个问题,描述了类似的行为:
- docker attach [container] hangs, requires input #8521
- docker attach hangs setting terminal state when attaching to container
Since you mention shell, I assume you have a shell already running. attach doesn't start a new process, so what is the expected behavior of connecting to the in/out/err streams of a running process? I didn't think about this. Of course this is the expected behavior of attaching to a running shell, but is it desirable?
是否有可能在 docker attach 上刷新 stdout/stderr 从而强制打印 shell 提示符,还是比这更复杂一些?这就是我个人 "expect" 附加到已经 运行ning shell.
时的情况如有必要,请随时关闭此问题,我只是觉得有必要记录下来并获得一些反馈。
- 取自comment on this github issue。您可以在本期的评论中找到更多见解。
如果您开始键入命令而不是 enter
,您将不会看到 extra 空提示行。如果你要 运行
$ docker exec -it ubuntu <container-ID-or-name> bash
其中 <container-ID-or-name>
是您 运行 docker run -it -d ubuntu
之后容器的 ID 或名称(因此您的问题中的 3aef6e642327 或 condescending_sammet)它将 运行 new 命令,因此没有附加到现有命令的 "stdout problem"。
例子
如果您在包含以下内容的目录中有一个 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
window。当然,您可以用 irrsi
替换另一个程序。
我遇到过一次,原因如下:
可能是容器内的bash命令正在执行"cat"命令。
因此,当您附加到容器(bash 命令)时,您实际上在 cat 命令中,该命令正在等待输入。 (text and/or ctrl-d写入文件)
如果您无法访问命令行,请确保您 运行 您的容器在启动时带有 -i
标志。
我 运行 在尝试附加到由其他人开发并且已经 运行 一个守护进程的容器时,我也陷入了这个问题。 (在这种情况下,它是 LinuxServer 的 transmission
docker 图像)。
问题:
发生的事情是终端出现在 'hang' 上,在那里输入任何内容都无济于事,也不会出现。只有 Ctrl-C
会把我踢出去。
docker run
、docker start
、docker attach
都没有成功,结果是我需要的命令(在使用 run
或 [=16 启动容器后=]) 是执行 bash
,因为您从中拉出的容器很可能没有 bash 已经 运行.
解决方案:
docker exec -it <container-id> bash
(您可以从 运行 docker ps -a
中找到 container-id
)。
这会将您拉入具有功能 bash 的实例,如 root
(假设您拉取的图像没有完成其他显式设置)。
我知道已接受的答案也包含了这一点,但决定 post 另一个更简洁和明显的答案,因为当我阅读它时,解决方案并没有为我弹出.
当我运行docker attach container-name
时,则没有任何输出,甚至Ctrl-c
也是无效的。所以,先试试
docker attach container-name --sig-proxy=false
然后ctrl-c
可以阻止它。为什么它没有输出任何东西?
只是因为容器没有输出。实际上我需要输入我的容器和 运行 一些 shell 命令。所以正确的命令是
docker exec -ti container-name bash
我今天遇到了类似的问题并且能够解决它:
这是我遇到的情况:
docker-compose logs -f nginx
Attaching to laradock_nginx_1
然后它会挂在那里,直到我通过 CTRL-C 退出:^CERROR: Aborting.
docker ps -a
显示该图像名称不存在应该被称为 laradock_nginx
的内容,所以我想我只是删除并重新 "up" 那个容器:
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
现在起作用了。
使用:docker exec -it CONTAINER_ID/NAME bash
改为:docker attach...