我使用-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.我无法获胜。
答案 0 :(得分:468)
2014年10月Docker team introduced docker exec
command: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
)将在后台运行,容器不会立即停止。
答案 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
。如果要在通常执行其他进程的容器中执行任意命令,可能需要尝试nsenter
或nsinit
。有关详细信息,请查看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`