为什么在检查创建的图像的env
时会得到按预期列出的图像环境变量,但是当我尝试访问这些环境变量之一(即$ PATH)时,我会而是获取我的本地计算机环境变量输出?
我相信我误解了docker环境变量的工作方式。我试图对Docker容器运行一些命令,并看到我认为意外的行为。我创建了一个简单的示例来尝试演示。
Dockerfile:
FROM node:12.13.0
ENV PATH="${PATH}:/custom-path/goes-here"
命令:
docker build . -tag env-test
docker run env-test /bin/bash -c "env"
docker run env-test /bin/bash -c "$PATH"
最后两个命令的预期输出。
docker run env-test /bin/bash -c "env".
...
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/custom-path/goes-here
...
docker run evn-test /bin/bash -c "echo $PATH"
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/custom-path/goes-here
最后两个命令的实际输出
docker run env-test /bin/bash -c "env".
...
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/custom-path/goes-here
...
docker run evn-test /bin/bash -c "echo $PATH"
/Users/local-machine-user/Downloads/google-cloud-sdk/bin:/Users/local-machine-user/.nvm/versions/node/v12.16.1/bin:/Library/Frameworks/Python.framework/Versions/3.7/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/Users/local-machine-user/Downloads/google-cloud-sdk/bin:/Library/Frameworks/Python.framework/Versions/3.7/bin
针对创建的映像运行echo $PATH
的输出将返回我的本地计算机$ PATH变量。什么?
我要做的主要事情是针对docker映像执行一个脚本,该脚本需要我在映像中设置的那些环境变量,但是该脚本失败了,因为该脚本使用的环境变量最终用于我的本地计算机,并且不是图片中指定的图片。
答案 0 :(得分:1)
在字符串中使用$PATH
-"echo \$PATH"
在运行此行时会发生什么:
docker run evn-test /bin/bash -c "echo $PATH"
Bash首先翻译$PATH
,然后将该字符串传递到docker容器中。因此,在容器内运行的命令是:
docker run evn-test /bin/bash -c "echo /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
答案 1 :(得分:1)
假设您要运行第三个示例
docker run env-test /bin/bash -c "echo $PATH"
这里发生的第一件事是您的本地shell处理此命令并执行其通常的扩展集。例如,扩展双引号中的环境变量引用。构建最终的命令行后,shell便会执行它。
通常有用的技巧是将echo
放在命令的前面
echo docker run env-test /bin/bash -c "echo $PATH"
这将向您显示本应运行但实际上未运行的命令。
要执行此操作,您需要使本地外壳程序不扩展环境变量,以便您在容器中启动的外壳程序可以执行此操作。单引号或反斜杠转义都适用于此
docker run env-test /bin/sh -c 'echo $PATH'
docker run env-test /bin/sh -c "echo \$PATH"
我要做的主要事情是针对docker映像执行一个脚本,该脚本需要在映像中设置的那些环境变量
解决此问题的最佳方法可能是编写一个普通的Shell脚本并将其COPY
插入图像。这节省了报价和混淆的层,在哪一层外壳正在处理变量之类的东西。如果您无法修改映像,则可以选择从主机绑定挂载脚本。
# If the script is in the image
docker run --rm env-test path-echoer.sh
# If not
docker run --rm -v $PWD:/scripts env-test /scripts/path-echoer.sh