
HereDoc 符号在 Bash、SQL、PHP 和其他脚本语言中已经使用了一段时间。它允许将非常长的命令分解成多个更易读的行,同时仍然被视为单个命令。
例如,在 PHP 中,你可能会有类似这样的 SQL 命令:
$sql = SELECT * FROM MyTable WHERE col1 < 100 and col2 > 200 ORDER BY name
相反,你可以通过在文件中将命令的各个部分拆分到多行来使其更易读,同时仍然将该命令作为一个整体执行,例如:
$sql = <<<SQL
SELECT * FROM MyTable
WHERE col1 < 100 and col2 > 200
ORDER BY name
SQL;
当然,这会增加一些字符,但许多人发现这种格式更容易阅读和理解。
在 2021 年,Docker 的 Buildkit 开始在 Dockerfile 中使用 HereDoc 符号。这使得 Dockerfile 看起来像是包含多个命令。但实际上,它们被分解成单个命令,重要的是,它们在生成的镜像中只成为一层,而不是 Dockerfile 中每一行都成为一层。
因此,与其使用类似这样的 Dockerfile:
FROM docker.io/redhat/ubi9-minimal as builder
RUN microdnf update
RUN microdnf -y install gcc
RUN microdnf -y install glibc-static
RUN microdnf -y install procps-ng
你可以使用类似这样的 Dockerfile:
FROM docker.io/redhat/ubi9-minimal as builder
RUN <<EOF
microdnf update
microdnf -y install gcc
microdnf -y install glibc-static
microdnf -y install procps-ng
EOF
这四个 microdnf 命令现在作为一个命令执行,在镜像中创建一个单层,而不是像第一个 Dockerfile 中那样每个 RUN 命令都创建一个层。虽然这个特定例子并没有更易读,但在许多情况下,Containerfile 可以通过使用 HereDoc 语法来提高可读性。
Buldah 团队收到了很多请求,要求将此功能整合到 Buildah 和 Podman 使用的 Containerfile 语法中。在 2023 年秋季,Aditya Rajan 创建了这个 拉取请求 来响应这个 问题,最初将此功能整合到 Buildah 中,用于 Containerfile 中的 `RUN`、`COPY` 和 `ADD` 命令。这在 Buildah v1.33 和 Podman v4.9 中实现。然而,对 HereDoc 代码进行了进一步的修改,这些修改在 Buildah v1.35 和 Podman v5.0 中实现,使其完全功能化。
现在,随着 Podman 和 Buildah 的最新版本发布,Containerfile 中的 HereDoc 语法已经得到完全完善。虽然它已经存在几个月了,但我认为 Podman 和 Buildah 的 Containerfile 中 HereDoc 语法的知名度还不高。我希望这篇文章能让你了解到 Podman 和 Buildah 现在可以使用的这种新的语法选项,并希望你能用它来让你的环境中的 Containerfile 更易读,同时还能减少生成的容器镜像中的层数。
发表评论