介绍
Docker 是一款容器化工具,可帮助开发人员创建和管理可移植的、与 Linux 兼容的容器。.
在开发或部署容器时,您经常需要查看正在运行的容器内部,以检查其当前状态或排查问题。为此,Docker 提供了 `docker exec` 命令,用于在正在运行的容器中执行应用程序。.
在本教程中,我们将学习 docker exec 命令以及如何使用它在 Docker 容器中运行命令并获得交互式 shell。.
先决条件
本教程假设您已安装 Docker 并且您的用户拥有运行 Docker 的权限。如果您需要以 root 用户身份运行 Docker,请记住在本教程中的命令前添加 sudo。.
有关如何在不使用 sudo 权限的情况下使用 Docker 的更多信息,请参阅我们的 Docker 安装教程中的“如何在不使用 sudo 的情况下运行 Docker 命令”部分。.
启动测试容器
要使用 docker exec 命令,您需要一个正在运行的 Docker 容器。如果您还没有容器,请使用以下 docker exec 命令启动一个测试容器:
docker run -d --name container-name alpine watch "date >> /var/log/date.log"
此命令会从官方 Alpine 镜像创建一个新的 Docker 容器。Alpine 是一个流行的 Linux 容器镜像,它使用 Alpine Linux,这是一个轻量级且精简的 Linux 发行版。.
我们使用 `-d` 标志将容器从终端分离并在后台运行。`--name container-name` 用于指定容器名称。您可以随意选择名称,也可以完全省略此参数,让 Docker 自动为新容器生成一个唯一的名称。.
接下来是 alpine,它指定了我们要用于容器的镜像。.
最后,我们还有“date >> /var/log/date.log”。这是我们要在容器中运行的命令。默认情况下,时钟每两秒运行一次您提供的命令。在本例中,时钟将运行的命令是 date >> /var/log/date.log。date 命令会打印当前日期和时间,如下所示:
Output
Fri Jul 23 14:57:05 UTC 2021>> /var/log/date.log 部分会将 date 命令的输出重定向到文件 /var/log/date.log。每隔两秒,文件中就会追加一行,几秒钟后,文件内容将类似于这样:
Output
Fri 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 容器,并提供一些关于它们的高级信息:
Output
CONTAINER 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
这将在指定的容器中运行 shell,并显示初始 shell 提示符。要退出容器,请键入 exit。 进入 按:
exit如果您的容器镜像包含更高级的 shell(例如 bash),则可以将上面的 sh 替换为 bash。.
在 Docker 容器中运行非交互式命令
如果您需要在正在运行的容器内运行命令,但不需要进行交互,请使用不带任何标志的 docker exec 命令:
docker exec container-name tail /var/log/date.log
此命令将对容器名称运行 `tail /var/log/date.log` 命令,并打印结果。默认情况下,`tail` 命令会打印文件的最后十行。如果您运行我们在第一部分中设置的测试容器,您将看到类似这样的内容:
Output
Mon 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` 命令相同。但是,此命令无需打开伪终端,而是通过单个命令返回相同的输出。.
在 Docker 容器的备用目录中运行命令
要在容器的特定目录中运行命令,请使用 --workdir 标志指定目录:
docker exec --workdir /tmp container-name pwd
此示例命令将 /tmp 目录设置为工作目录,然后运行 pwd 命令,该命令会打印当前工作目录:
Output
/tmp
pwd 命令已确认工作目录为 /tmp。.
在 Docker 容器中以不同用户身份运行命令
要在容器内以其他用户身份运行命令,请添加 --user 标志:
docker exec --user guest container-name whoami
此操作使用访客用户在容器中运行 whoami 命令。whoami 命令会打印出当前用户的用户名:
Output
guestwhoami 命令确认容器的当前用户是访客。.
将环境变量传递给 Docker 容器
有时需要将环境变量与运行命令一起传递给容器。-e 标志允许您指定环境变量:
docker exec -e TEST=sammy container-name env
此命令将 TEST 环境变量设置为 sammy,然后在容器内运行 env 命令。env 命令随后会打印所有环境变量:
Output
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=76aded7112d4
TEST=sammy
HOME=/rootTEST 变量设置为 sammy。.
要设置多个变量,请为每个变量重复使用 -e 标志:
docker exec -e TEST=sammy -e ENVIRONMENT=prod container-name env
如果要传递一个包含环境变量的文件,可以使用 –env-file 标志。.
首先,用文本编辑器创建文件。这里我们用 nano 编辑器新建一个文件,但你可以使用任何你用得顺手的编辑器:
nano .env
我们使用 .env 作为文件名,因为它是使用此类文件管理版本控制之外的信息的流行标准。.
请在文件中逐行写入 KEY=value 变量,如下所示:
TEST=sammy
ENVIRONMENT=prod保存并关闭文件。要保存文件并退出 nano 编辑器,请按 CTRL+O,然后按 ENTER 保存,再按 CTRL+X 退出。.
现在运行 docker exec 命令,并在 –env-file 后指定正确的文件名:
docker exec --env-file .env container-name env
Output
PATH=/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
“找不到容器”错误表示指定的容器不存在,也可能是容器名称拼写错误。请使用 `docker ps` 命令列出正在运行的容器,并仔细检查容器名称。.
Error response from daemon: Container 2a94aae70ea5dc92a12e30b13d0613dd6ca5919174d73e62e29cb0f79db6e4ab is not running
此消息表示容器存在但已停止。您可以使用 `docker start container-name` 命令启动容器。
Error response from daemon: Container container-name is paused, unpause the container before exec
错误信息“容器已暂停”很好地解释了问题所在。在继续操作之前,您需要使用 `docker unpause container-name` 命令恢复容器的运行。.
结果
在本教程中,我们学习了如何在运行中的 Docker 容器中执行命令,以及执行命令时的一些命令行选项。.
有关 Docker 的更多信息,请访问我们的 Docker 标签页面,其中包含 Docker 教程、Docker 相关问答页面等的链接。.









