如何使用dockerexec在Docker容器中运行命令

来自菜鸟教程
跳转至:导航、​搜索

介绍

Docker 是一个容器化工具,可帮助开发人员创建和管理可移植的、一致的 Linux 容器。

在开发或部署容器时,您通常需要查看正在运行的容器内部以检查其当前状态或调试问题。 为此,Docker 提供了 docker exec 命令在已经运行的容器中运行程序。

在本教程中,我们将了解 docker exec 命令以及如何使用它来运行命令并在正在运行的 Docker 容器中获取交互式 shell。

先决条件

本教程假设您已经安装了 Docker,并且您的用户有权运行 docker。 如果您需要以 root 用户身份运行 docker,请记住在本教程中的命令前添加 sudo

有关在没有 sudo 访问权限的情况下使用 Docker 的更多信息,请参阅我们的 如何安装 Docker 教程的 Executing the Docker Command without Sudo 部分。

启动测试容器

要使用 docker exec 命令,您需要一个正在运行的 Docker 容器。 如果您还没有容器,请使用以下 docker run 命令启动测试容器:

docker run -d --name container-name alpine watch "date >> /var/log/date.log"

此命令从 官方 alpine 映像 创建一个新的 Docker 容器。 这是一个流行的 Linux 容器镜像,它使用 Alpine Linux,一个轻量级、最小的 Linux 发行版。

我们使用 -d 标志将容器与终端分离并在后台运行它。 --name container-name 将容器命名为 container-name。 您可以在此处选择您喜欢的任何名称,或者完全不使用它,让 Docker 自动为新容器生成一个唯一名称。

接下来我们有 alpine,它指定了我们要用于容器的图像。

最后我们有 watch "date >> /var/log/date.log"。 这是我们要在容器中运行的命令。 watch 将重复运行你给它的命令,默认每两秒一次。 在这种情况下 watch 将运行的命令是 date >> /var/log/date.logdate 打印当前日期和时间,如下所示:

OutputFri Jul 23 14:57:05 UTC 2021

命令的 >> /var/log/date.log 部分重定向来自 date 的输出并将其附加到文件 /var/log/date.log。 每两秒就会在文件中添加一个新行,几秒钟后它看起来像这样:

OutputFri Jul 23 15:00:26 UTC 2021
Fri Jul 23 15:00:28 UTC 2021
Fri Jul 23 15:00:30 UTC 2021
Fri Jul 23 15:00:32 UTC 2021
Fri Jul 23 15:00:34 UTC 2021

在下一步中,我们将学习如何查找 Docker 容器的名称。 如果您已经有一个要定位的容器,但您不确定它的名称是什么,这将非常有用。

查找 Docker 容器的名称

我们需要向 docker exec 提供我们要使用的容器的名称(或容器 ID)。 我们可以使用 docker ps 命令找到这些信息:

docker ps

此命令列出服务器上运行的所有 Docker 容器,并提供有关它们的一些高级信息:

OutputCONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
76aded7112d4   alpine    "watch 'date >> /var…"   11 seconds ago   Up 10 seconds             container-name

在此示例中,容器 ID 和名称被突出显示。 您可以使用任何一个来告诉 docker exec 使用哪个容器。

如果您想重命名容器,请使用 docker rename 命令:

docker rename container-name new-name

接下来,我们将运行几个使用 docker exec 在正在运行的 Docker 容器中执行命令的示例。

在 Docker 容器中运行交互式 Shell

如果您需要在 Docker 容器中启动交互式 shell,可能是为了探索文件系统或调试正在运行的进程,请使用带有 -i-t 标志的 docker exec

-i 标志保持输入对容器开放,-t 标志创建一个 shell 可以附加到的伪终端。 这些标志可以像这样组合:

docker exec -it container-name sh

这将在指定容器中运行 sh shell,为您提供基本的 shell 提示。 要退出容器,输入 exit 然后按 ENTER

exit

如果您的容器映像包含更高级的 shell,例如 bash,您可以将上面的 sh 替换为 bash

在 Docker 容器中运行非交互式命令

如果您需要在正在运行的 Docker 容器中运行命令,但不需要任何交互性,请使用不带任何标志的 docker exec 命令:

docker exec container-name tail /var/log/date.log

此命令将在 container-name 容器上运行 tail /var/log/date.log,并输出结果。 默认情况下,tail 命令将打印出文件的最后十行。 如果您正在运行我们在第一部分中设置的演示容器,您将看到如下内容:

OutputMon Jul 26 14:39:33 UTC 2021
Mon Jul 26 14:39:35 UTC 2021
Mon Jul 26 14:39:37 UTC 2021
Mon Jul 26 14:39:39 UTC 2021
Mon Jul 26 14:39:41 UTC 2021
Mon Jul 26 14:39:43 UTC 2021
Mon Jul 26 14:39:45 UTC 2021
Mon Jul 26 14:39:47 UTC 2021
Mon Jul 26 14:39:49 UTC 2021
Mon Jul 26 14:39:51 UTC 2021

这基本上与为 Docker 容器打开一个交互式 shell(如上一步中使用 docker exec -it container-name sh 所做的那样)然后运行 tail /var/log/date.log 命令相同。 但是,该命令不是打开 shell,运行命令,然后关闭 shell,而是在单个命令中返回相同的输出,而不打开伪终端。

在 Docker 容器的备用目录中运行命令

要在容器的某个目录中运行命令,请使用 --workdir 标志指定目录:

docker exec --workdir /tmp container-name pwd

此示例命令将 /tmp 目录设置为工作目录,然后运行 pwd 命令,打印出当前工作目录:

Output/tmp

pwd命令确认工作目录为/tmp

在 Docker 容器中以不同用户身份运行命令

要在容器内以其他用户身份运行命令,请添加 --user 标志:

docker exec --user guest container-name whoami

这将使用 guest 用户在容器中运行 whoami 命令。 whoami 命令打印出当前用户的用户名:

Outputguest

whoami 命令确认容器的当前用户是 guest

将环境变量传递给 Docker 容器

有时您需要将环境变量与要运行的命令一起传递到容器中。 -e 标志允许您指定环境变量:

docker exec -e TEST=sammy container-name env

此命令将 TEST 环境变量设置为等于 sammy,然后在容器内运行 env 命令。 env 命令然后打印出所有环境变量:

OutputPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=76aded7112d4
TEST=sammy
HOME=/root

TEST 变量设置为 sammy

要设置多个变量,请为每个变量重复 -e 标志:

docker exec -e TEST=sammy -e ENVIRONMENT=prod container-name env

如果您想传入一个充满环境变量的文件,您可以使用 --env-file 标志来实现。

首先,使用文本编辑器制作文件。 我们将在此处使用 nano 打开一个新文件,但您可以使用任何您喜欢的编辑器:

nano .env

我们使用 .env 作为文件名,因为这是使用这些类型的文件来管理版本控制之外的信息的流行标准。

KEY=value 变量写入文件,每行一个,如下所示:

.env

TEST=sammy
ENVIRONMENT=prod

保存并关闭文件。 要保存文件并退出 nano,请按 CTRL+O,然后按 ENTER 保存,然后按 CTRL+X 退出。

现在运行 docker exec 命令,在 --env-file 之后指定正确的文件名:

docker exec --env-file .env container-name env
OutputPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=76aded7112d4
TEST=sammy
ENVIRONMENT=prod
HOME=/root

设置文件中的两个变量。

您可以使用多个 --env-file 标志指定多个文件。 如果文件中的变量相互重叠,则命令中最后列出的文件将覆盖以前的文件。

常见错误

在使用 docker exec 命令时,可能会遇到几个常见的错误:

Error: No such container: container-name

No such container 错误表示指定的容器不存在,可能表示容器名称拼写错误。 使用 docker ps 列出正在运行的容器并仔细检查名称。

Error response from daemon: Container 2a94aae70ea5dc92a12e30b13d0613dd6ca5919174d73e62e29cb0f79db6e4ab is not running

not running 消息表示容器存在,但已停止。 您可以使用 docker start container-name 启动容器

Error response from daemon: Container container-name is paused, unpause the container before exec

Container is paused 错误很好地解释了这个问题。 在继续之前,您需要使用 docker unpause container-name 取消暂停容器。

结论

在本教程中,我们学习了如何在正在运行的 Docker 容器中执行命令,以及执行此操作时可用的一些命令行选项。

有关 Docker 的更多信息,请参阅我们的 Docker 标记页面 ,其中包含指向 Docker 教程、与 Docker 相关的问答页面等的链接。

有关安装 Docker 的帮助,请查看 如何在 Ubuntu 20.04 上安装和使用 Docker。