1. 概述
本文将展示如何在Docker中更新PATH
变量。首先,我们将全局更新它。然后,我们将限制更改仅应用于一组指令。
2. 全局更新PATH
变量
ENV
语句可以用来更新PATH
变量。让我们编写一个Dockerfile示例来展示这种行为:
FROM ubuntu:latest
RUN echo $PATH
ENV PATH="$PATH:/etc/profile"
RUN echo $PATH
第一行表示我们使用最新的Ubuntu镜像。我们还在ENV
指令之前和之后记录了PATH
变量的值。
现在让我们构建我们的镜像:
$ docker build -t baeldungimage .
#4 [1/3] FROM docker.io/library/ubuntu:latest
#5 [2/3] RUN echo /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#5 0.683 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#6 [3/3] RUN echo /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/etc/profile
#6 0.893 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/etc/profile
如预期的那样,/etc/profile
被添加到了PATH
中。
3. 只为一组指令更新PATH
我们将使用RUN
指令运行一个sh脚本来向PATH
添加内容。然后,我们将在同一个RUN
语句中添加另一个指令。这将在同一个RUN
命令内的后续指令中使用更新后的PATH
值。我们还将记录全局PATH
变量,以确认它未改变。
以下是我们的新Dockerfile:
FROM ubuntu:latest
RUN echo $PATH
RUN export PATH="$PATH:/etc/profile"; echo $PATH
RUN echo $PATH
我们现在可以构建镜像:
$ docker build -t baeldungimage .
#7 [1/4] FROM docker.io/library/ubuntu:latest
#4 [2/4] RUN echo /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#4 0.477 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#5 [3/4] RUN export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/etc/profile"; echo /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#5 0.660 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/etc/profile
#6 [4/4] RUN echo /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#6 0.661 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
日志证实,在导出PATH
变量后,其值被同一RUN
命令内后续指令所使用。然而,全局变量并未改变。
4. 在shell会话中更新PATH
接下来,我们将看到如何仅在shell会话中更新PATH
。首先,我们将修改.bashrc
文件,使其在每个shell会话开始时更新PATH
。然后,我们将启动一个shell会话以检查此行为。
4.1. 编辑.bashrc
文件
我们将编辑.bashrc
文件,在每个shell会话开始时导出新的PATH
。为此,我们将运行一个快速脚本向原始文件追加导出,以确保这一更改不会影响全局PATH
变量。
以下是新的Dockerfile:
FROM ubuntu:latest
RUN echo $PATH
RUN echo "export PATH=$PATH:/etc/profile" >> ~/.bashrc
RUN cat ~/.bashrc
RUN echo $PATH
另外,请注意我们使用了[cat](/linux/files-cat-more-less#cat)
命令查看文件。
现在让我们构建镜像:
$ docker build -t baeldungimage .
#4 [1/5] FROM docker.io/library/ubuntu:latest
#5 [2/5] RUN echo /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#5 0.447 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#6 [3/5] RUN echo "export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/etc/profile" >> ~/.bashrc
#7 [4/5] RUN cat ~/.bashrc
#7 0.956 # ~/.bashrc: executed by bash(1) for non-login shells.
#7 0.956 # see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
#7 0.956 # for examples
#7 0.956
#7 0.956 # If not running interactively, don't do anything
#7 0.956 [ -z "$PS1" ] && return
[... .bashrc full content]
#7 0.956 export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/etc/profile
#7 DONE 1.0s
#8 [5/5] RUN echo /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#8 0.867 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
如您所见,全局PATH
没有改变。但是,确实已将导出行添加到文件末尾。因此,每当加载.bashrc
时,它都会为运行的shell更新PATH
变量。
4.2. 运行容器的交互模式
现在,让我们关注我们之前看到的.bashrc
文件输出的前几行。这些行来自原始文件。它明确地说明了“如果不在交互模式下运行,则不做任何操作”。
理解这一点很重要:当我们构建Dockerfile时,RUN
命令是非交互式的。因此,我们无法仅源代码.bashrc
文件并在构建期间运行脚本来检查路径是否已更新。
相反,我们可以运行容器的交互模式,并打开一个shell会话:
$ docker run -it --name interactiveimage baeldungimage
root@18781222594f:/# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/etc/profile
一旦进入shell会话,我们就打印了PATH
。我们可以看到/etc/profile
被添加,确认.bashrc
文件已被考虑。
5. 结论
在这篇教程中,我们看到了如何在Docker中更新PATH
变量。最初,我们全局更新了变量,但我们也学习了如何通过更严格的限制来更新它。
正如往常一样,代码可以在GitHub上找到https://github.com/Baeldung/ops-tutorials/tree/main/docker-modules/docker-images。