exec表单中的Docker运行命令不工作

exec表单中的Docker运行命令不工作,docker,alpine,Docker,Alpine,我正在建立一个基于阿尔卑斯山的码头工人形象 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

我正在建立一个基于阿尔卑斯山的码头工人形象

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,:未找到


我试过使用
bin/sh
sh
bin/ash
ash
。所有这些都是相同的错误。

我已经使用Docker好几年了,直到你提出问题,我才知道有shell | exec表单用于
RUN
;-)

问题在于,您的命令包含环境变量(
$COLOR
),并且没有使用
exec
表单替代|求值

见:


“与shell表单不同,exec表单不调用命令shell。这意味着正常的shell处理不会发生”

我已经使用Docker好几年了,我不知道(直到你提出问题)有用于运行
的shell | exec表单

问题在于,您的命令包含环境变量(
$COLOR
),并且没有使用
exec
表单替代|求值

见:


“与shell表单不同,exec表单不调用命令shell。这意味着正常的shell处理不会发生”

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
结果:

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

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
结果:

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

你完全正确..谢谢!这个错误有点误导..当它说
/bin/sh:[sh,:not found
时,我只是关注第一个参数。你完全正确..谢谢!这个错误有点误导..我只是关注第一个参数,当它说
/bin/sh:[sh,:not found