为什么Dockerfile中的RUN命令会打印出echo选项?

10

使用最新的Docker for Mac,在最新版的macOS上。

我有一个Dockerfile:

FROM debian:8
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update -y -q \
    && apt-get install -y -q apt-utils \
    && apt-get upgrade -y -q \
    && apt-get install -y -q ssh build-essential libssl-dev libffi-dev python-dev python-pip python-six openjdk-7-jdk \
    && mkdir -p /etc/ansible \
    && echo -e "[ssh_connection]\nssh_args = -o ControlMaster=no -o ControlPersist=60s\n" > /etc/ansible/ansible.cfg

问题在于echo命令。该命令产生的文件内容为:

-e [ssh_connection]
ssh_args = -o ControlMaster=no -o ControlPersist=60s

加上 -e 选项也会被打印出来,更疯狂的是这个选项已经被echo命令捕捉到了,因为可以看到换行符被解析了。实际上,如果我连接到容器并再次运行相同的命令,则会获得正确的文件内容。我认为这可能是由于 docker build 在 RUN 中引用每个参数造成的问题,但即使我运行 echo "-e" "X\nY" 命令,结果也会打印出:

X
Y

有人知道为什么会发生这种情况吗?

3个回答

20

尝试运行:

RUN bash -c 'echo -e ...'

来源


2
我刚刚用/bin/echo替换了echo,因为我不想处理双引号。 - RokL
1
不行,仍然只是得到一个愚蠢的字面行,显示了我在Dockerfile中放置的内容,根本没有透露值是多少。 - Nathan McKaskle

1
阅读https://github.com/docker/docker/issues/8949,我理解奇怪行为的原因取决于解释 shell。
在我的情况下,运行 Ubuntu 镜像,只需删除-e即可使该行正确格式化:
RUN echo "# User rules for foobar\n\
            foobar ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/nopasswd

结果是:

# User rules for foobar
            foobar ALL=(ALL) NOPASSWD:ALL

-10
最好不要在 RUN 中使用双引号。始终使用单引号或使用 ENV 变量设置环境变量。
例如:
echo '******* Installing PPA pack ********'

ENV JAVA_HOME /usr/bin/java

1
这不是海报所询问的内容,也不是有效的Dockerfile语法(我认为)。 - Daniel R. Livingston

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接