ai2*_*2ys 11 docker dockerfile
在我的 docker 文件中,我为带有点的版本号定义了一个变量,我想将其替换为下划线以供进一步使用。
ARG ABC_VERSION=1.2.3
ARG SOME_OTHER_VARIABLE=/dir_name/abc_${ABC_VERSION//./_}
Run Code Online (Sandbox Code Playgroud)
不幸的是,我收到以下错误。
failed to process "/dir_name/abc_${ABC_VERSION//./_}": missing ':' in substitution
Run Code Online (Sandbox Code Playgroud)
我需要在 dockerfile 中使用“.”多次使用版本号。一次使用“_”,我不喜欢定义两个变量。
有人知道如何解决这个问题吗?
编辑:我想利用该功能来替换字符的实际代码的一部分如下所示。
ARG EXPAT_VERSION=2.1.0
# ...
RUN wget https://github.com/libexpat/libexpat/releases/download/R_${EXPAT_VERSION//./_}/expat-${EXPAT_VERSION}.tar.gz \
&& tar xzf expat-${EXPAT_VERSION}.tar.gz \
&& cp -R expat-${EXPAT_VERSION}/lib ./xmp_sdk/third-party/expat \
&& rm -r expat-${EXPAT_VERSION} && rm expat-${EXPAT_VERSION}.tar.gz
Run Code Online (Sandbox Code Playgroud)
我看到在tensorflow-gpu dockerfiles中使用了类似的东西:
ARG CUDA=10.1
#...
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
cuda-command-line-tools-${CUDA/./-} #...
Run Code Online (Sandbox Code Playgroud)
Eri*_*kMD 15
该${parameter/pattern/string}语法实际上是 Bash 功能(参见shell 参数扩展),而不是 POSIX 功能。
根据官方文档,Dockerfile指令仅支持:
\n\n$var\n${var}\n${var:-word} \xe2\x86\x92 if var is not set then word is the result;\n${var:+word} \xe2\x86\x92 if var is set then word is the result, otherwise the empty string\nRun Code Online (Sandbox Code Playgroud)\n\n所以这个问题没有“直接”的解决方案,但是如果最终在某些 shell 命令(在RUN,ENTRYPOINT或CMD指令中)中使用您想要替换的变量,您也可以保留初始值按原样(没有替换),然后稍后替换它?
我的意思是,例如以下Dockerfile:
\n\nFROM debian\n\nARG ABC_VERSION=1.2.3\nENV SOME_OTHER_VARIABLE=/app/${ABC_VERSION}\n\nWORKDIR /app\n\nRUN /bin/bash -c \'touch "${SOME_OTHER_VARIABLE//./_}"\'\n\n# RUN touch "${SOME_OTHER_VARIABLE//./_}"\n# would raise /bin/sh: 1: Bad substitution\n\nCMD ["/bin/bash", "-c", "ls -hal \\"${SOME_OTHER_VARIABLE//./_}\\""]\nRun Code Online (Sandbox Code Playgroud)\n\n作为旁白:
\n\nARG SOME_OTHER_VARIABLE为ENV SOME_OTHER_VARIABLE只是为了能够从 中使用它CMD。ENTRYPOINT指令CMD应该以 exec 形式 \xe2\x88\x92 \xe2\x88\x92 编写,CMD ["\xe2\x80\xa6", "\xe2\x80\xa6"]而不是以 shell 形式编写(例如,参见该问题:CMD 在 Dockerfile 中的 ENTRYPOINT 之后不运行)。或者作为替代解决方法,您可能希望将版本号拆分为主要版本号、次要版本号、补丁,以编写类似这样的内容?
\n\nARG MAJOR=1\nARG MINOR=2\nARG PATCH=3\nARG ABC_VERSION=$MAJOR.$MINOR.$PATCH\nARG SOME_OTHER_VARIABLE=/dir_name/abc_${MAJOR}_${MINOR}_${PATCH}\n\xe2\x80\xa6\nRun Code Online (Sandbox Code Playgroud)\n\n在OP的编辑之后,我想一个问题是我在“解决方法1”中提到的这一行的相对冗长:
\n\n\xe2\x80\xa6\nRUN /bin/bash -c \'touch "${SOME_OTHER_VARIABLE//./_}"\'\nRun Code Online (Sandbox Code Playgroud)\n\n为了缓解这一问题,Docker 允许用 Bash 替换隐含的 shell(默认情况下sh),Bash 确实支持您感兴趣的 shell 参数扩展。关键点是必须在命令之前编写以下指令RUN(并且该指令是正是OP提到的Dockerfile的一部分):
SHELL ["/bin/bash", "-c"]\nRun Code Online (Sandbox Code Playgroud)\n\n因此,Dockerfile 变为:
\n\n\xe2\x80\xa6 \nARG ABC_VERSION=1.2.3\n\nSHELL ["/bin/bash", "-c"]\nRUN touch "/dir_name/abc_${ABC_VERSION//./_}" \\\n && ls -hal "/dir_name/abc_${ABC_VERSION//./_}"\nRun Code Online (Sandbox Code Playgroud)\n\n或利用一些临时环境变量:
\n\n\xe2\x80\xa6 \nARG ABC_VERSION=1.2.3\n\nSHELL ["/bin/bash", "-c"]\nRUN export SOME_OTHER_VARIABLE="/dir_name/abc_${ABC_VERSION//./_}" \\\n && touch "$SOME_OTHER_VARIABLE" \\\n && ls -hal "$SOME_OTHER_VARIABLE"\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
9105 次 |
| 最近记录: |