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