Docker exec quoting variables Docker exec quoting variables bash bash

Docker exec quoting variables


Ok, I found a way to do it, all you need to do is evaluate command with bash

docker exec -it <container id> bash -c 'echo something-${CLI}'

returns something-/usr/local/bin/myprogram

If the CLI environment variable is not already set in the container, you can also pass it in such as:

docker exec -it -e CLI=/usr/local/bin/myprogram <container id> bash -c 'echo something-${CLI}'

See the help file:

 docker exec --help Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...] Run a command in a running containerOptions:-d, --detach               Detached mode: run command in the background-e, --env list             Set environment variables....


In it's original revision docker exec -it <my container> '${CLI} do something' with the expectation that ${CLI} will be substituted with /usr/local/bin/myprogram (as the exec COMMAND) and everything after passed as ARG's to /usr/local/bin/myprogram will not work, this is clearly documented: https://docs.docker.com/engine/reference/commandline/exec/

COMMAND should be an executable, a chained or a quoted command will not work. Example:

docker exec -ti my_container "echo a && echo b" will not work, but

docker exec -ti my_container sh -c "echo a && echo b" will.

Following the documentation, this will work as expected: docker exec -ti my_container sh -c "${CLI} foo", ${CLI} will be be executed after variable expansion and the argument(s) passed to the shell script set in ${CLI} (e.g. sh -c /usr/local/bin/myprogram foo).

Alternatively you could set the ENTRYPOINT to your script and pass in arguments with CMD or at the command line with docker run for example:

Given the below directory structure:

.├── Dockerfile└── example.sh

The Dockerfile contents:

FROM ubuntu:18.04COPY example.sh /binRUN chmod u+x /bin/example.shENTRYPOINT ["/bin/example.sh"]CMD ["bla"]

And the example.sh script contents:

#!/bin/bashecho $1

The CMD specified in the Dockerfile after the ENTRYPOINT will be the default argument for your script and you can override the default argument on the command line (assuming that the image is built and tagged as example:0.1):

user@host> docker run --rm example:0.1blauser@host> docker run --rm example:0.1 "arbitrary text"arbitrary text

Note: this is my go to article for differences between ENTRYPOINT and CMD in Dockerfile's: https://medium.freecodecamp.org/docker-entrypoint-cmd-dockerfile-best-practices-abc591c30e21