在传递给 docker 运行 命令的变量中转义 $

Escape $ in variable passed to docker run command

当从 makefile 执行命令时,我不知道如何转义美元符号以访问在 docker 中的环境中定义的变量。

这是我的设置的最小表示,我正在尝试回应 /mypath

define create-test
so-test-:
    docker run \
        --rm \
        -t \
        --env SRC="/mypath" \
        ubuntu:xenial \
        /bin/bash -c ""
endef


$(eval $(call create-test,1,echo $SRC ))
$(eval $(call create-test,2,echo $$SRC ))
$(eval $(call create-test,3,echo $$$$SRC ))
$(eval $(call create-test,4,echo $$$$$$$$SRC ))

输出是

$ make so-test-1
docker run --rm -t --env SRC="/mypath" ubuntu:xenial /bin/bash -c "echo RC "
RC
$ make so-test-2
docker run --rm -t --env SRC="/mypath" ubuntu:xenial /bin/bash -c "echo RC "
RC
$ make so-test-3
docker run --rm -t --env SRC="/mypath" ubuntu:xenial /bin/bash -c "echo $SRC "

$ make so-test-4
docker run --rm -t --env SRC="/mypath" ubuntu:xenial /bin/bash -c "echo $$SRC "
6526SRC

我知道环境变量已设置,因为它会显示我是否在容器中调用 env

我应该如何转义 SRC 变量,以便它在 docker 容器中的 shell 运行 中展开?

您感到困惑的原因是您遇到的报价问题与制造无关。它与 shell.

有关

与编写制作食谱一样,您应该首先确保您可以 运行 来自 shell 提示符的命令并且它会执行您想要的操作。只有在那之后你才应该把它放在食谱中。在您的情况下,假设您在 shell 提示符下 运行:

docker run \
    --rm \
    -t \
    --env SRC="/mypath" \
    ubuntu:xenial \
    /bin/bash -c "echo $SRC"

这行不通。为什么不?因为, shell 会在调用命令之前展开双引号内的所有变量。这意味着您的 docker 命令实际上将其作为参数:

docker run \
    --rm \
    -t \
    --env SRC="/mypath" \
    ubuntu:xenial \
    /bin/bash -c "echo "

因为 shell 扩展了 $SRC 变量,它是空的(它不会被设置直到 docker 开始,但是这个扩展是由 shell在 docker 开始之前)。

您需要使用单引号以避免 shell 扩展您的变量:

docker run \
    --rm \
    -t \
    --env SRC="/mypath" \
    ubuntu:xenial \
    /bin/bash -c 'echo $SRC'

现在您应该能够让您的 makefile 配方按预期工作。