如何在保留新行的同时在Dockerfile中编写多行命令?


84

我想在Dockerfile中编写以下RUN命令。但是,泊坞窗不保留新行。

RUN echo "[repo] \
name            = YUM Repository \
baseurl         = https://example.com/packages/ \
enabled         = 1 \
gpgcheck        = 0" > /etc/yum.repos.d/Repo.repoxyz

我知道\每一行的末尾都转义了新行。但是,有什么办法可以写多行来保存新行?


您是否使用非* nix平台?因为这对我在Linux上正常工作。
用户

@user,我正在使用Linux。
Venkata Jaswanth

Answers:


114

您可以将称为“ ANSI-C引用” $'...'它最初是ksh93的功能,但现在可以在bash,zsh,mksh,FreeBSD shbusybox的ash中使用(但仅当使用ENABLE_ASH_BASH_COMPAT编译时才可用)。

由于默认情况下RUN/bin/sh用作shell,因此您需要先使用SHELL指令切换到bash之类的东西。

以开头的命令$',以结束的命令,'\n\用于换行符,如下所示:

SHELL ["/bin/bash", "-c"]

RUN echo $'[repo] \n\
name            = YUM Repository \n\
baseurl         = https://example.com/packages/ \n\
enabled         = 1 \n\
gpgcheck        = 0' > /etc/yum.repos.d/Repo.repoxyz

4
它是bash语法。有关更多信息,
请参见此

13
请解释你在做什么,不只是下降不透明的解决方案
爱德华·洛佩兹

25
请注意:该$' ... \n\ 技术取决于dockerRUN使用的shell是bash。在某些系统(例如Ubuntu)上,RUN使用的shell/bin/sh通常是一个链接,dash该链接不是NOTbash并且不了解$'语法。
佚名

2
正如@Anon所说,如果在bash以外的其他地方运行,则不会起作用。(在Oh My Zsh任何一个都不起作用)
拉法

1
@Anon很好,它确实在使用shell的Alpine linux(目前我在3.10.2)上工作。
suchoss '19

52

我用过printf。使用“ \ n”将所有文本写在一行中。

执行中:

RUN printf 'example \ntext \nhere' >> example.txt

插入:

example
text
here

在example.txt中


19

您可以使用:

RUN echo -e "\
[repo] \n\
name            = YUM Repository \n\
baseurl         = https://example.com/packages/ \n\
enabled         = 1 \n\
gpgcheck        = 0\
" > /etc/yum.repos.d/Repo.repoxyz

这样,您将可以快速查看文件内容。您只需要知道,您需要以每行结尾\\n在需要时插入。


1
这需要echo -e解释\n
帕特里克·伯格纳

5

由于新行\n不适用于,因此我最终使用了上面列出的示例echo

RUN printf 'example \n\
text \n\
here' >> example.txt

预期会产生以下结果:

example
text
here

您的答案与CTodea的答案有何不同?
教父

@TheGodfather这是一个多行示例。更好地回答原始问题。
谢尔盖

2

可能对您有帮助(https://github.com/jen-soft/pydocker

[Dockerfile.py]

from pydocker import DockerFile  # sudo pip install -U pydocker

d = DockerFile(base_img='debian:8.2', name='jen-soft/custom-debian:8.2')

d.RUN_bash_script('/opt/set_repo.sh', r'''
cat >/etc/apt/sources.list <<EOL
deb     http://security.debian.org/ jessie/updates main
deb-src http://security.debian.org/ jessie/updates main
EOL
apt-get clean && apt-get update
''')

d.EXPOSE = 80
d.WORKDIR = '/opt'
d.CMD = ["python", "--version"]

# d.generate_files()
d.build_img()

# sudo wget -qO- https://get.docker.com/ | sh

python Dockerfile.py
docker images

-1

您可以多次执行RUN来完成文件:

RUN echo "[repo]" >> /etc/yum.repos.d/Repo.repoxyz
RUN echo "name            = YUM Repository" >> /etc/yum.repos.d/Repo.repoxyz
RUN echo "baseurl         = https://example.com/packages/" >> /etc/yum.repos.d/Repo.repoxyz
RUN echo "enabled         = 1" >> /etc/yum.repos.d/Repo.repoxyz
RUN echo "gpgcheck        = 0" >> /etc/yum.repos.d/Repo.repoxyz

这可能不是最佳解决方案,因为它会为每个RUN命令创建一个新层。尽管如此,每一层都将与您所做的更改一样大,在这种情况下,更改的大小为字节(第一个RUN层应为7字节)。

此解决方案的好处是它将与所有外壳一起使用。


1
&&为了更好的缓存目的,减少日志记录和缩短Dockerfile构建时间,可能更好地并置这些命令
JohannesB
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.