首页 文章

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

提问于
浏览
352

我用 -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

但是,如果我开始它,它无论如何都会退出 . grab 22.我不能赢 .

12 回答

  • 0

    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 )将在后台运行,容器不会立即停止 .

  • 67

    Pipe a command to 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主机上 .

  • 83

    要扩展katrmr 's answer, if the container is stopped and can'由于错误而启动,您需要 commit 它到图像 . 然后你可以在新图像中启动bash:

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

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

    以下示例从映像启动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"
    

    就这些 .

  • 6

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

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

  • 13

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

    To start an existing container which is stopped

    docker start <container-name/ID>
    

    To stop a running container

    docker stop <container-name/ID>
    

    Then to login to the interactive shell of a container

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

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

  • 2

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

    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”方法不能将参数更改为已停止的容器 . )

  • 416

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

  • 2

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

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

    一定要改变 <CONTAINER_ID/CONTAINER_NAME>

  • 38

    您的容器将 exit ,因为您给出的命令将结束 . 使用以下选项使其保持活动状态:

    • -i 即使未连接,也要保持STDIN打开 .

    • -t 分配伪TTY .

    所以你的新 run 命令是:

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

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

    docker exec -it CONTAINER_ID /bin/bash
    

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

  • 1

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

    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
    

相关问题