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

时间:2014-10-02 02:34:25

标签: docker

我使用-d创建了一个容器,因此它不是交互式的。

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.我无法获胜。

20 个答案:

答案 0 :(得分:468)

2014年10月Docker team introduced docker exec commandhttps://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)将在后台运行,容器不会立即停止

答案 1 :(得分:267)

您的容器将退出,因为您提供的命令将结束。使用以下选项使其保持活动状态:

  • -i即使没有附加,也要保持STDIN处于打开状态。
  • -t分配伪TTY。

所以你的新run命令是:

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

如果您想附加到已经运行的容器:

docker exec -it CONTAINER_ID /bin/bash

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

答案 2 :(得分:85)

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

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

答案 3 :(得分:83)

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

启动已停止的现有容器

docker start <container-name/ID>

停止正在运行的容器

docker stop <container-name/ID>

然后登录容器的交互式shell

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

启动现有容器并通过一个命令附加到该容器

docker start -ai <container-name/ID>

请注意,这将在退出时停止容器。但一般来说,你需要启动容器,在完成后连接并停止它。

答案 4 :(得分:39)

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

Sven Dowideit在Docker论坛上解释说容器绑定到他们的进程(并且Docker无法改变已停止容器的进程,似乎至少应该归因于其内部结构:https://github.com/docker/docker/issues/1437)。因此,基本上唯一的选择是commit容器到图像,run用不同的命令。

https://forums.docker.com/t/run-command-in-stopped-container/343
(我相信“ENTRYPOINT with arguments”方法也不起作用,因为你仍然无法将参数更改为已停止的容器。)

答案 5 :(得分:16)

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

答案 6 :(得分:14)

创建容器并逐个发送命令:

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

答案 7 :(得分:7)

这是我使用上面的CDR LDN答案和我找到的答案here组成的综合答案。

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

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"

就是这样。

答案 8 :(得分:3)

我想指出,最重要的答案是有点误导。

执行docker run的问题是每次都会创建一个新容器。但是,在某些情况下,我们想重新使用旧容器或不占用新容器的空间。

(给出clever_bardeen是创建的容器的名称...)

对于OP,请执行以下命令,以确保首先运行docker映像:

docker start clever_bardeen

然后,使用以下命令执行docker容器:

docker exec -it clever_bardeen /bin/bash

答案 9 :(得分:2)

不幸的是,无法使用ENTRYPOINT的参数覆盖docker run --entrypoint来实现此目标。

  

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

答案 10 :(得分:2)

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

答案 11 :(得分:2)

将命令传递给stdin

必须删除-t才能使其正常工作:

echo 'touch myfile' | sudo docker exec -i CONTAINER_NAME bash

有时使用CLI选项会更方便。

经过测试:

sudo docker run --name ub16 -it ubuntu:16.04 bash

然后在另一个shell上:

echo 'touch myfile' | sudo docker exec -i ub16 bash

然后在第一个shell:

ls -l myfile

在Docker 1.13.1,Ubuntu 16.04主机上。

答案 12 :(得分:2)

如果您尝试运行shell脚本,则需要以bash身份运行它(基于velop答案)。

docker exec -it containerid bash -c /path/to/your/script.sh

答案 13 :(得分:1)

我为节点红色的容器制作了这个,并解决了我的问题:

NODEREDNAME=mynodered
# Create a new node red container
docker run -it -p 1880:1880 -v "$(pwd)/data":/data --name $NODEREDNAME -d nodered/node-red-docker

# Open a shell in the container (THAT ANSWERS THE QUESTION)
docker exec -it $NODEREDNAME bash -c "cd /data & npm install node-red-node-mongodb"

# Restart the container to load the new nodes
docker stop $NODEREDNAME
docker start $NODEREDNAME

答案 14 :(得分:1)

我通常使用这个:

    docker exec -it my-container-name bash

与正在运行的容器进行持续交互。

答案 15 :(得分:0)

简单回答:同时启动和附加。在这种情况下,你正在完成你所要求的。

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

请务必更改<CONTAINER_ID/CONTAINER_NAME>

答案 16 :(得分:0)

对于Mac:

$ docker exec -it <container-name> sh

如果要以root用户身份连接:

$ docker exec -u 0 -it <container-name> sh

答案 17 :(得分:0)

# docker exec -d container_id command 

例如:

# docker exec -d xcdefrdtt service jira stop 

答案 18 :(得分:0)

我正在运行Windows容器,我需要在docker容器中查找创建和复制的文件和文件夹。

为此,我使用了以下docker entrypoint命令来使命令提示符在容器内运行或附加到容器。

ENTRYPOINT ["C:\\Windows\\System32\\cmd.exe", "-D", "FOREGROUND"]

这帮助我将命令提示符附加到容器,并使容器保持活动状态。 :)

答案 19 :(得分:0)

一种快速的方法来恢复和访问最近退出的容器:

docker start -a -i `docker ps -q -l`