Docker中RUN命令变量展开差异:为何两示例结果不同?
问题:为何两个Dockerfile示例中环境变量获取结果不同?
示例1
Dockerfile代码
FROM ubuntu:latest SHELL ["/bin/bash", "-c"] RUN echo "export MY_VARIABLE=my_value" >> ~/.profile RUN cat ~/.profile RUN "source ~/.profile && echo env variable4: $MY_VARIABLE"
构建命令
sudo docker build --no-cache -t hello-image --progress plain .
输出结果
variable4:my_value
示例2
Dockerfile代码
FROM ubuntu:latest RUN echo "export MY_VARIABLE=my_value" >> ~/.profile RUN cat ~/.profile RUN /bin/bash -c "source ~/.profile && echo env variable4: $MY_VARIABLE"
构建命令
sudo docker build --no-cache -t hello-image --progress plain .
输出结果
variable4:
原因分析
核心差异在于变量替换的时机和SHELL指令的作用:
示例1的逻辑:
通过SHELL ["/bin/bash", "-c"]指定了后续所有RUN指令默认用bash执行。最后一条RUN的双引号属于bash语法,$MY_VARIABLE会在bash执行source ~/.profile完成变量导入后才被解析替换,自然能拿到my_value。示例2的问题:
未指定SHELL时,Docker默认用/bin/sh -c执行RUN指令。最后一条RUN里的/bin/bash -c "...",外层的/bin/sh会先解析双引号内容,$MY_VARIABLE在这一步就被替换了——但此时该变量在/bin/sh环境中不存在,直接变成空字符串。后续bash启动后再source变量,也没法改变已经被替换好的空值。
如果要修复示例2,只需把$转义,让变量替换交给bash处理:
RUN /bin/bash -c "source ~/.profile && echo env variable4: \$MY_VARIABLE"
内容的提问来源于stack exchange,提问作者nayak0765
相关产品推荐
相关产品推荐

