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

wnavrhmk  于 2023-02-07  发布在  Docker
关注(0)|答案(7)|浏览(239)

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

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

我知道每行末尾的\会转义新行,但是,有没有什么方法可以写多行并保留新行呢?

iezvtpos

iezvtpos1#

你可以在$'...'中使用所谓的“ANSI-C quoting”,它最初是ksh 93的一个特性,但是现在它在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
ctehm74n

ctehm74n2#

使用printf允许单个RUN命令输出多行文本,使用\n插入换行符。
执行:

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

附录:

example
text
here

到文件example.txt

hpcdzsge

hpcdzsge3#

您可以使用:

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

txu3uszq

txu3uszq4#

由于新的\n行不适用于echo,所以我最终使用了上面列出的示例的组合。

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

如预期的那样,它将生成以下内容:

example
text
here
wmomyfyw

wmomyfyw5#

从Docker 18.09和Dockerfile语法1.4开始,Dockerfiles原生支持heredocs(即您在这里寻找的内容)!

  1. Enable BuildKit,例如通过设置DOCKER_BUILDKIT=1
    1.将这一行添加到您的Dockerfile的顶部:
# syntax=docker/dockerfile:1.4

或文档中推荐的

# syntax=docker/dockerfile:1

1.这样重写你的heredoc:

COPY <<EOF /etc/yum.repos.d/Repo.repoxyz
[repo]
name            = YUM Repository
baseurl         = https://example.com/packages/
enabled         = 1
gpgcheck        = 0
EOF

您还可以使用它在单个RUN块中运行多个bash命令,等等。更多详细信息:Docker blog post,停靠文件语法文档。

h7wcgrx3

h7wcgrx36#

可能对你有帮助(https://github.com/jen-soft/pydocker
[www.example.com]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
vbkedwbf

vbkedwbf7#

可以多次执行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字节)。
此解决方案的好处是它将适用于所有壳。

相关问题