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

介绍

Docker是一个集装箱化工具,帮助开发人员创建和管理便携式,一致的Linux容器。

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

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

前提条件

本教程假定您已经安装了 Docker,并且您的用户有运行docker的权限。如果您需要作为 root用户运行docker,请记住将sudo预定为本教程中的命令。

有关使用 Docker 没有sudo访问的更多信息,请参阅我们如何安装 Docker 教程的 执行 Docker 命令没有 Sudo部分。

开始测试集装箱

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

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

此命令会从 官方的Alpine 图像创建一个新的Docker容器,这是一个使用Alpine Linux(https://alpinelinux.org/)的流行的Linux容器图像,是一种轻量级、最小型的Linux发行版。

我们使用d标志将容器从我们的终端分开,并在后台运行。--name container-name将命名容器container-name

接下来,我们有alpine,它指定了我们想为容器使用的图像。

最后,我们有观看日期 /var/log/date.log。这是我们想要在容器中运行的命令。观看将重复执行你给出的命令,默认情况下每两秒钟一次。

1[secondary_label Output]
2Fri Jul 23 14:57:05 UTC 2021

该命令的> /var/log/date.log部分将输出从date重定向到/var/log/date.log文件中。

1[secondary_label Output]
2Fri Jul 23 15:00:26 UTC 2021
3Fri Jul 23 15:00:28 UTC 2021
4Fri Jul 23 15:00:30 UTC 2021
5Fri Jul 23 15:00:32 UTC 2021
6Fri Jul 23 15:00:34 UTC 2021

在下一步中,我们将学习如何找到 Docker 容器的名称,如果您已经有您正在瞄准的容器,但您不确定其名称。

查找 Docker 容器的名称

我们需要提供我们想要使用的容器的名称(或容器ID)。

1docker ps

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

1[secondary_label Output]
2CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
376aded7112d4 alpine    "watch 'date >> /var…"   11 seconds ago Up 10 seconds container-name

在此示例中,将突出显示容器 ID 和名称,您可以使用docker exec来说明要使用哪个容器。

如果您想更名您的容器,请使用docker更名命令:

1docker rename container-name new-name

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

在 Docker 容器中运行互动壳

如果您需要在 Docker 容器内部启动交互式壳,特别是探索文件系统或调试运行过程,请使用docker exec-i-t旗帜。

-i旗保持输入对容器开放,而-t旗创建了一个伪终端,壳可以连接到。

1docker exec -it container-name sh

这将在指定的容器中运行sh壳,为您提供一个基本的壳提示. 要退出容器,键入exit,然后按ENTER:

1exit

如果你的容器图像包含一个更先进的壳,如bash,你可以用上面的bash代替sh

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

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

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

此命令将在容器名称容器上运行tail /var/log/date.log,并输出结果.默认情况下,tail命令将打印文件的最后十行。

 1[secondary_label Output]
 2Mon Jul 26 14:39:33 UTC 2021
 3Mon Jul 26 14:39:35 UTC 2021
 4Mon Jul 26 14:39:37 UTC 2021
 5Mon Jul 26 14:39:39 UTC 2021
 6Mon Jul 26 14:39:41 UTC 2021
 7Mon Jul 26 14:39:43 UTC 2021
 8Mon Jul 26 14:39:45 UTC 2021
 9Mon Jul 26 14:39:47 UTC 2021
10Mon Jul 26 14:39:49 UTC 2021
11Mon Jul 26 14:39:51 UTC 2021

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

在 Docker 容器中的替代目录中运行命令

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

1docker exec --workdir /tmp container-name pwd

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

1[secondary_label Output]
2/tmp

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

在 Docker 容器中作为不同的用户运行命令

若要在容器内作为不同的用户运行命令,请添加--user旗:

1docker exec --user guest container-name whoami

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

1[secondary_label Output]
2guest

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

将环境变量转移到 Docker 容器中

有时你需要将环境变量传输到一个容器中,以及运行命令. `-e' 旗允许你指定一个环境变量:

1docker exec -e TEST=sammy container-name env

此命令将TEST环境变量设置为sammy,然后在容器内部运行env命令。

1[secondary_label Output]
2PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
3HOSTNAME=76aded7112d4
4TEST=sammy
5HOME=/root

TEST变量设置为sammy

要设置多个变量,重复每个变量的-e旗:

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

如果你想通过一个充满环境变量的文件,你可以用--env-file旗帜来做到这一点。

首先,使用文本编辑器创建文件. 我们将在这里打开一个新的文件,其中有nano,但您可以使用您舒适的任何编辑器:

1nano .env

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

将您的KEY=value变量写入文件中,每行一个,如下:

1[label .env]
2TEST=sammy
3ENVIRONMENT=prod

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

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

1docker exec --env-file .env container-name env
1[secondary_label Output]
2PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
3HOSTNAME=76aded7112d4
4TEST=sammy
5ENVIRONMENT=prod
6HOME=/root

文件中的两个变量被设置。

您可以使用多个 --env-file 旗帜来指定多个文件. 如果文件中的变量相互重叠,则命令中最后列出的任何文件都将取代以前的文件。

常见错误

使用docker exec命令时,您可能会遇到一些常见的错误:

1Error: No such container: container-name

没有这样的集装箱错误意味着指定的集装箱不存在,并可能显示错误的集装箱名称。

1Error response from daemon: Container 2a94aae70ea5dc92a12e30b13d0613dd6ca5919174d73e62e29cb0f79db6e4ab is not running

此「不執行」訊息意味著容器存在,但已停止使用,您可以使用「docker start container-name」開始容器。

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

集装箱暂停错误解释了问题相当好. 您需要在继续之前用docker unpause container-name暂停集装箱。

结论

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

有关 Docker 的更多信息,请参阅我们的 Docker 标签页面,该页面包含链接到 Docker 教程、与 Docker 相关的 Q&A 页面等。

有关安装 Docker 的帮助,请参阅 如何在 Ubuntu 20.04 上安装和使用 Docker

Published At
Categories with 技术
Tagged with
comments powered by Disqus