如何在现有的Docker容器上运行命令?

我用-d创build了一个容器,所以它不是交互式的。

 docker run -d shykes/pybuilder bin/bash 

我看到容器已经退出:

 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d6c45e8cc5f0 shykes/pybuilder:latest "bin/bash" 41 minutes ago Exited (0) 2 seconds ago clever_bardeen 

现在我想在机器上运行偶然的命令并退出。 只是为了得到回应。

我试图启动机器。 我试图附加。 我以为我可以打电话与容器run ,但似乎并不被允许。 使用start似乎运行,然后迅速存在。

退出后我想回到交互模式。

我试过了:

 docker attach d6c45e8cc5f0 

但是我得到:

 2014/10/01 22:33:34 You cannot attach to a stopped container, start it first 

但是,如果我启动它,它仍然退出。 赶上22.我不能赢。

在2014年10月, Docker团队介绍了docker exec命令 : https : //docs.docker.com/engine/reference/commandline/exec/

所以,现在只要知道它的ID(或名称)就可以在正在运行的容器中运行任何命令:

 docker exec -it <container_id_or_name> echo "Hello from container!" 

请注意, exec命令仅适用于已经运行的容器。 如果容器当前已停止,则需要先使用以下命令运行它:

 docker run -it -d shykes/pybuilder /bin/bash 

这里最重要的是-d选项,代表detached 。 这意味着您最初提供给容器( /bin/bash )的命令将在后台运行,并且容器不会立即停止

你的容器将会退出,因为你的命令将会结束。 使用以下选项来保持它的生命:

  • 即使未连接,也要保持STDIN打开。
  • -t分配一个伪TTY。

所以你的新run命令是:

 docker run -it -d shykes/pybuilder bin/bash 

如果您想要附加到已经运行的容器,请执行以下操作:

 docker exec -it CONTAINER_ID /bin/bash 

在这些例子中, /bin/bash被用作命令。

为了扩展katrmr的答案,如果容器被停止,并且由于错误而无法启动,则需要将其commit给图像。 然后你可以在新的图像中启动bash:

 docker commit [CONTAINER_ID] temporary_image docker run --entrypoint=bash -it temporary_image 

这里的一些答案是误导性的,因为它们涉及正在运行的容器,而不是停止。

Sven Dowideit在Docker论坛上解释说,容器绑定到他们的进程(而且Docker不能改变停止容器的进程,至less由于其内部结构: https : //github.com/docker/docker/issues / 1437 )。 所以,基本上唯一的select是将容器commit到一个图像,并用不同的命令run

https://forums.docker.com/t/run-command-in-stopped-container/343
(我相信“带参数的ENTRYPOINT ”方法也是行不通的,因为你仍然无法将参数改变为停止的容器。)

所以我觉得答案比上面的许多误导性答案简单。

启动已停止的现有容器

 docker start <container-name/ID> 

停止正在运行的容器

 docker stop <container-name/ID> 

然后login到容器的交互式shell

 docker exec -it <container-name/ID> bash 

创build一个容器并向其发送一个命令:

 docker create --name=my_new_container -it ubuntu docker start my_new_container // ps -a says 'Up X seconds' docker exec my_new_container /path/to/my/command // ps -a still says 'Up X+Y seconds' docker exec my_new_container /path/to/another/command 

这是我使用上面的CDR LDN答案和我在这里find的答案组成的综合答案。

以下示例从映像启动Arch Linux容器,然后使用pacman工具在该容器上安装git

 sudo docker run -it -d archlinux /bin/bash sudo docker ps -l sudo docker exec -it [container_ID] script /dev/null -c "pacman -S git --noconfirm" 

就这些。

我必须使用bash -c来运行我的命令: docker exec -it CONTAINER_ID bash -c "mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql mysql"

假设映像使用缺省入口点/bin/sh -c ,运行/bin/bash将在守护进程模式( -d )下立即退出。 如果您希望此容器运行交互式shell,请使用-it而不是-d 。 如果要在通常执行另一个进程的容器中执行任意命令,则可能需要尝试nsenternsinit 。 有关详细信息, 请参阅https://blog.codecentric.de/en/2014/07/enter-docker-container/

不幸的是,使用ENTRYPOINT docker run --entrypoint参数来覆盖ENTRYPOINT是不可能实现这个目标的。

注意:你可以使用–entrypoint覆盖ENTRYPOINT设置,但是这只能将二进制设置为exec(不会使用sh -c)。

简单的答案:同时启动并附加。 在这种情况下,你正在做你所要求的。

 docker start <CONTAINER_ID/CONTAINER_NAME> && docker attach <CONTAINER_ID/CONTAINER_NAME> 

请务必更改<CONTAINER_ID/CONTAINER_NAME>