通过 .env 文件的命令扩展为 `docker 运行` 生成参数

Generating parameters for `docker run` through command expansion from .env files

我在以相对通用的方式将一些环境参数传递给 docker run 时遇到了一些问题。

我们的第一次迭代是通过这些行将 .env 文件加载到环境中:

set -o allexport;
. "${PROJECT_DIR}/.env";
set +o allexport;

然后手动键入 --env VARNAME=$VARNAME 作为 docker run 命令的选项。但是当你有几十个变量时,这会很烦人。

然后我们尝试用 --env-file .env 传递文件,它 似乎 可以工作,但它没有,因为它不能很好地与引用变量值。

这是我开始做 crazy/ugly 事情的地方。基本想法是做类似的事情:

set_docker_parameters()
{
    grep -v '^$' "${PROJECT_DIR}/.env" | while IFS= read -r LINE; do
        printf " -e %s" "${LINE}"
    done
}

docker run $(set_docker_parameters) --rm image:label command

其中解析的行类似于 VARIABLE="value"VARIABLE='value'VARIABLE=value。空行被管道 grep.

丢弃

但是docker run总是抱怨没有被正确调用。当我扩展 set_docker_parameters 的结果时,我得到了预期的结果,当我复制它的结果并替换 $(set_docker_parameters) 时,docker run 也按预期工作,完美无瑕。

知道我做错了什么吗?

非常感谢!

P.S.: 我试图让我的脚本 100% POSIX 兼容,所以我更喜欢任何不依赖 Bash 特定功能的解决方案.

根据@jordanm 的评论,我设计了以下解决方案:

docker_run_wrapper()
{
    # That's not ideal, but in any case it's not directly related to the question.
    cmd=

    set --; # Unset all positional arguments ($@ will be emptied)

    # We don't have arrays (we want to be POSIX compatible), so we'll
    # use $@ as a sort of substitute, appending new values to it.
    grep -v '^$' "${PROJECT_DIR}/.env" | while IFS= read -r LINE; do
        set -- "$@" "--env";
        set -- "$@" "${LINE}";
    done

    # We use $@ in a clearly non-standard way, just to expand the values
    # coming from the .env file.
    docker run "$@" "image:label" /bin/sh -c "${cmd}";
}

话又说回来,这不是我为特定用例编写的代码,而是显示基本思想的简化代码。如果您可以依赖 Bash,那么它可以更简洁,不重载 $@ 并使用数组。