I want to use an env
variable within Docker container.
By using a Makefile
.
This variable only exists in Docker container.
I wrote a Makefile
for reusing code in CICD pipeline.
But I have problems with right escaping of the passing variable.
Makefile
execute:
@echo $(COMMAND)
docker exec -it my-dev-container $(COMMAND)
Empty result of Makefile
$ make execute COMMAND="bash -c 'echo $VARIABLE_ONLY_EXIST_IN_CONTAINER'"
bash -c echo
<< EMPTY >>
Expected result of Makefile:
$ make execute COMMAND="bash -c 'echo $VARIABLE_ONLY_EXIST_IN_CONTAINER'"
I_AM_A_VARIABLE_VALUE_WITHIN_THE_CONTAINER
Without Makefile it’s working:
docker exec -it my-dev-container bash -c 'echo $VARIABLE_ONLY_EXIST_IN_CONTAINER'
I_AM_A_VARIABLE_VALUE_WITHIN_THE_CONTAINER
Any ideas how to escape the string correctly?
2
Answers
Make variables are simple strings, and Make doesn’t have any way to escape a multi-word string so that it’s safe to pass to a shell context. For this to work as you’ve shown it, you need to escape the string in your host shell so that Make receives the string it needs to run the subcommand.
In your setup, you need
COMMAND
to have the valuewhere the single quotes and dollars sign are part of the string. When you type
make
, you need to quote this (and especially the dollars sign) on the host:You don’t seem to be using Make as a build system here, and the fragment you’ve shown doesn’t suggest dependencies on any other build rules. It may be simpler to just run the
docker exec
command you’ve shown (or, better, a standalonedocker run
command), or to use some other technology like a shell script for a wrapper tool.You have two escaping problems. The first problem is you have to escape the
$
from the shell. By using double-quotes you are not escaping the$
from the shell: runningecho "$foo"
prints the value of the shell variablefoo
, it doesn’t print the string$foo
.So when you run
make COMMAND="bash -c 'echo $VARIABLE_ONLY_EXIST_IN_CONTAINER'"
, the shell will expand$VARIABLE_ONLY_EXIST_IN_CONTAINER
before it even invokes make which is not what you want. To avoid this you either have to use single-quotes or use a backslash:Secondly, you need to escape the
$
from make because that’s also a special character to make. If you only use the above then make will expand$V
as a make variable which also won’t do what you want. In make you escape a$
by writing it twice, like$$
You have two choices: you can either add the escaping on the command line, like this:
Or if you’re sure that you never want to expand anything in
COMMAND
as a make variable or function, you can use the GNU Makevalue
function, like this:and running
make COMMAND="bash -c 'echo $VARIABLE_ONLY_EXIST_IN_CONTAINER'"
will do what you want.