Makefile escaping variables in bash command to Docker container

34 Views Asked by At

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?

1

There are 1 best solutions below

0
MadScientist On BEST ANSWER

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: running echo "$foo" prints the value of the shell variable foo, 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:

make COMMAND="bash -c 'echo \$VARIABLE_ONLY_EXIST_IN_CONTAINER'"

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:

make COMMAND="bash -c 'echo \$\$VARIABLE_ONLY_EXIST_IN_CONTAINER'"

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 Make value function, like this:

execute:
         @echo $(value COMMAND)
         docker exec -it my-dev-container $(value COMMAND)

and running make COMMAND="bash -c 'echo \$VARIABLE_ONLY_EXIST_IN_CONTAINER'" will do what you want.