Windows镜像Dockerfile中ARG参数的条件RUN命令语法问题
解决Windows Dockerfile中CMD条件RUN命令的语法问题
问题根源
你当前的错误是混淆了Bash和Windows CMD的语法规则:
- Bash用
[ ]做条件判断,换行用反引号` - CMD的
if判断不需要[ ],换行必须用脱字符^,且变量引用和等式的引号位置要严格对应
正确的CMD条件RUN写法
修改后的Dockerfile片段如下:
FROM mcr.microsoft.com/windows/servercore:ltsc2022 # 可添加默认值,避免未传参时出错 ARG VSVersion=2022 SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] WORKDIR /Temp # 切换回CMD shell SHELL ["cmd", "/S", "/C"] RUN if "%VSVersion%"=="2019" (^ curl -SL --output vs_buildtools.exe https://aka.ms/vs/16/release/vs_buildtools.exe ^ && vs_buildtools.exe --installPath C:\BuildTools --quiet --wait --norestart --nocache ^ --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended --includeOptional ^ ) else if "%VSVersion%"=="2022" (^ curl -SL --output vs_buildtools.exe https://aka.ms/vs/17/release/vs_buildtools.exe ^ && vs_buildtools.exe --installPath C:\BuildTools --quiet --wait --norestart --nocache ^ --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended --includeOptional ^ )
关键语法说明
- CMD的IF格式:
if "%变量%"=="值" (命令块),括号必须紧跟条件,不能有空格 - 换行符:每行末尾用
^(注意^后面不能有任何空格或换行) - 变量引用:CMD中必须用
%变量名%,且前后加引号避免变量为空时语法报错 - 多命令串联:用
&&保证前序命令成功后才执行后续操作
可选:用PowerShell做条件判断
如果你更熟悉PowerShell语法,也可以保留PowerShell作为SHELL,写法更直观:
FROM mcr.microsoft.com/windows/servercore:ltsc2022 ARG VSVersion=2022 SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] WORKDIR /Temp RUN if ($env:VSVersion -eq '2019') { Invoke-WebRequest -Uri 'https://aka.ms/vs/16/release/vs_buildtools.exe' -OutFile 'vs_buildtools.exe'; .\vs_buildtools.exe --installPath C:\BuildTools --quiet --wait --norestart --nocache ` --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended --includeOptional; } else { Invoke-WebRequest -Uri 'https://aka.ms/vs/17/release/vs_buildtools.exe' -OutFile 'vs_buildtools.exe'; .\vs_buildtools.exe --installPath C:\BuildTools --quiet --wait --norestart --nocache ` --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended --includeOptional; }
内容的提问来源于stack exchange,提问作者lbpoundz
相关产品推荐
相关产品推荐

