从makefile执行命令时,我无法弄清楚如何转义美元符号以访问docker环境中定义的变量。
这是我设置的最小代表,我正在尝试回应/mypath
define create-test
so-test-$1:
docker run \
--rm \
-t \
--env SRC="/mypath" \
ubuntu:xenial \
/bin/bash -c "$2"
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运行中展开?
答案 0 :(得分:1)
您感到困惑的原因是您所引用的引用问题与make无关。它与shell有关。
与编写make recipes一样,您应首先确保您可以从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启动之前它不会被设置,但是这个扩展在docker启动之前由shell发生)。
您需要使用单引号来避免shell扩展您的变量:
docker run \
--rm \
-t \
--env SRC="/mypath" \
ubuntu:xenial \
/bin/bash -c 'echo $SRC'
现在你应该可以让你的makefile配方按预期工作了。