我正在构建一个基于 Alpine 的 docker 镜像。
FROM alpine
RUN apk update \
&& apk add lighttpd \
&& rm -rf /var/cache/apk/*
ENV COLOR red
COPY ./index.html /var/www/localhost/htdocs
RUN /bin/ash -c 'echo abcd'
#working
RUN /bin/ash -c "echo $COLOR; sed -i -e 's/red/\$COLOR/g' /var/www/localhost/htdocs/index.html; cat /var/www/localhost/htdocs/index.html;"
#not working
# RUN ["sh", "-c", "echo $COLOR; sed -i -e 's/red/\$COLOR/g' /var/www/localhost/htdocs/index.html; cat /var/www/localhost/htdocs/index.html;"]
CMD ["lighttpd","-D","-f","/etc/lighttpd/lighttpd.conf"]
当我以 shell 形式运行时它工作正常,但是当我以 exec 形式运行时它给出了
<块引用>/bin/sh: [sh,: not found
我尝试使用 bin/sh
、sh
、bin/ash
、ash
。所有人都犯了同样的错误。
答案 0 :(得分:2)
Shell 负责扩展变量,但只有双引号中的变量才会被扩展。
你的错误来自\
之前的错误$COLOR
,实际上你从shell中获取值没有任何意义,正确的方法是:
RUN ["sh", "-c", "echo $COLOR; sed -i -e \"s/red/$COLOR/g\" /var/www/localhost/htdocs/index.html; cat /var/www/localhost/htdocs/index.html;"]
显示效果的最小示例,仅供参考:
Dockerfile:
FROM alpine
ENV COLOR rednew
RUN echo "red" > /tmp/index.html
RUN ["sh", "-c", "sed -i -e \"s/red/$COLOR/g\" /tmp/index.html; cat /tmp/index.html;"]
结果:
$ docker build -t abc:1 . --no-cache
Sending build context to Docker daemon 5.632kB
Step 1/4 : FROM alpine
---> 28f6e2705743
Step 2/4 : ENV COLOR rednew
---> Running in 05c43146fab0
Removing intermediate container 05c43146fab0
---> 28ea1434e626
Step 3/4 : RUN echo "red" > /tmp/index.html
---> Running in 2c8fbbc5fd10
Removing intermediate container 2c8fbbc5fd10
---> f884892ad8c4
Step 4/4 : RUN ["sh", "-c", "sed -i -e \"s/red/$COLOR/g\" /tmp/index.html; cat /tmp/index.html;"]
---> Running in 6930b3d03438
rednew
Removing intermediate container 6930b3d03438
---> b770475672cc
Successfully built b770475672cc
Successfully tagged abc:1
答案 1 :(得分:1)
我已经使用 Docker 几年了,但我不知道(直到您提出问题)RUN
有 shell|exec 表单;-)
问题在于您的命令包含环境变量 ($COLOR
),并且 exec
形式没有替代|评估。
见:
https://docs.docker.com/engine/reference/builder/#run
“与 shell 形式不同,exec 形式不调用命令 shell。这意味着不会发生正常的 shell 处理”