$> docker exec -it my_container zsh
在容器中,我想要终止某个进程。我尝试使用ctrl+c
组合键,但发现它需要很长的时间才能完成。我查阅了一些资料,似乎ctrl+c
在容器中与预期有些不同。我的问题是,如何解决在容器中使用ctrl+c
的问题?
$> docker exec -it my_container zsh
在容器中,我想要终止某个进程。我尝试使用ctrl+c
组合键,但发现它需要很长的时间才能完成。我查阅了一些资料,似乎ctrl+c
在容器中与预期有些不同。我的问题是,如何解决在容器中使用ctrl+c
的问题?
docker 0.6.5
开始,您可以在docker run命令中添加-t
,这将附加一个pseudo-TTY
。然后,您可以键入Control-C
以分离容器而不终止它。-t
和-i
,则Control-C将终止容器。当使用-i
和-t
时,您必须使用Control-P Control-Q
以分离而不终止。$ ID=$(sudo docker run -t -d ubuntu /usr/bin/top -b)
$ sudo docker attach $ID
Control-P Control-Q
$ sudo docker ps
$ ID=$(sudo docker run -t -i -d ubuntu /usr/bin/top -b)
$ sudo docker attach $ID
Control-C
$ sudo docker ps
容器不存在(已被终止)。如果在第二个示例中,您键入Control-P
Control-Q
而不是Control-C,容器仍将继续运行。
使用docker-entrypoint.sh bash脚本包装程序,阻塞容器进程并能够捕获ctrl-c。这个bash示例可能会有所帮助: https://rimuhosting.com/knowledgebase/linux/misc/trapping-ctrl-c-in-bash
#!/bin/bash
# trap ctrl-c and call ctrl_c()
trap ctrl_c INT
function ctrl_c() {
echo "** Trapped CTRL-C"
}
for i in `seq 1 5`; do
sleep 1
echo -n "."
done
有时候,当我使用ctrl-C来终止容器内的一个进程时,容器会退出。
此外,我也发现容器中运行的进程有时会留下僵尸进程。
我发现,如果使用--init
开关启动容器,则可以解决上述问题。这似乎使我的容器以更加“正常、符合UNIX预期的方式”运作。
注意:--init
与-i
不同,后者是--interactive
的简写。
如果您想了解有关--init
开关的详细信息,请在包含有关docker run
信息的Docker网页上阅读相关内容。该网页上的信息显示:“在容器内部运行一个init进程来转发信号和回收进程。”
Ctrl+C
时,它也会忽略Ctrl+\
。 - eNcawhen your docker terminal is not responding to Ctrl+C/Ctrl+D/Ctrl+/, try these steps:
#1>> Open another terminal session and enter the command:
**`docker container ls`**
or
**`docker container list`**
#2>> locate the container id from the above list and issue the docker container stop command:
**`docker stop <<containerId>>`**
#3>> next time when you launch the docker container, use the flag "**-it**" to respond to the Ctrl+C event
docker run -it <>
Now you can stop ,with control+C
当我尝试在 Docker 容器中运行 Rust 可执行文件 mdbook
时,遇到了类似的问题。该可执行文件启动了一个简单的 Web 服务器,我想通过按下 Ctrl+C 来停止它,但并没有起作用。
$ docker -ti --rm -p 4321:4321 my-docker-image mdbook serve --hostname 0.0.0.0 --port 4321
2019-08-16 14:00:11 [INFO] (mdbook::book): Book building has started
2019-08-16 14:00:11 [INFO] (mdbook::book): Running the html backend
2019-08-16 14:00:11 [INFO] (mdbook::cmd::serve): Serving on: http://0.0.0.0:4321
2019-08-16 14:00:11 [INFO] (ws): Listening for new connections on 0.0.0.0:3001.
2019-08-16 14:00:11 [INFO] (mdbook::cmd::watch): Listening for changes...
^C^C
受到@NID回答的启发,我使用通用的bash脚本docker-entrypoint.sh
封装了mdbook可执行文件,这解决了问题(无需显式捕获INT信号)。
$ docker -ti --rm -p 4321:4321 my-docker-image docker-entrypoint.sh mdbook serve --hostname 0.0.0.0 --port 4321
2019-08-16 14:00:11 [INFO] (mdbook::book): Book building has started
2019-08-16 14:00:11 [INFO] (mdbook::book): Running the html backend
2019-08-16 14:00:11 [INFO] (mdbook::cmd::serve): Serving on: http://0.0.0.0:4321
2019-08-16 14:00:11 [INFO] (ws): Listening for new connections on 0.0.0.0:3001.
2019-08-16 14:00:11 [INFO] (mdbook::cmd::watch): Listening for changes...
^C $
docker-entrypoint.sh
文件的内容非常简单:
#!/bin/bash
$@
docker-entrypoint.sh
:-) 然后通过 ADD
命令将此文件添加到你的 Dockerfile 中。 - eNca我试过了@Remy Orange提供的--init
解决方案并且它对我有效。在一些搜索后,包括i)如何在docker run中使用 --init 参数,ii) Tini的优势是什么? 和 iii) init,我写下了以下详细解决方案:
tini
:$ sudo apt update && sudo apt install tini
tini
或者版本太旧,请参考此处的Dockerfile添加tini。--init
运行您的Docker容器:docker run -ti --init --rm YOUR_DOCKER_CONTAINER_EXMAPLE bash
然后您进入 Docker 容器,可以运行一些进程或实验。例如,运行 Python 代码,然后您可以使用 Ctrl + C
键来取消这个 Python 代码,就像在 Ubuntu 上(即在 Docker 容器之外的普通终端)所做的那样。
查看我的示例截图:
init
参数来将信号转发到容器:version: "2.4"
services:
web:
image: alpine:latest
init: true
docker exec
命令中加入选项 -ti
。我浪费了大约2个小时。
新命令--(工作正常)
sudo docker stop
sudo docker rm
sudo docker run -t
旧命令 --(不再起作用)
sudo docker stop
sudo docker rm
sudo docker run
Ctrl + C
sudo docker start
对我而言,只有在使用docker run -it <容器ID/名称>
运行容器之后,Ctrl+C才能起作用。
对于仍然遇到这个问题的人,对我有用的是Ctrl+d
。 Ctrl+c
或Ctrl+z
都不起作用。
ctrl+c
是用于退出容器,而这不是我想要的。我想停止我手动启动的程序。 - Jeanluca Scaljeri-it
是个好主意了。顺便说一下,这也很容易记住。只需要输入docker run -it ...
! :-D - RayLuo