介绍
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。